What is the point of signed char?

P

Peter Nilsson

[I think the intended example is really...

int8_t *ip = ...;
char *cp = ip;
]
... The point, I guess, is that the above code fragment violates a
constraint on any possible conforming implementation. If an
implementation chose to take advantage of the "as if" rule, as
Lawrence Kirby suggested, the lack of a diagnostic would demonstrate
that the implementation is non-conforming.

True, but any implementation can issue a diagnostic for any construct
whether it violates a constraint or not.
Agreed, *except* that you can detect the non-conformance by the lack
of a diagnostic.

True, but there is nothing in the standard that says a given
implementation
_cannot_ issue a diagnostic in a circumstance that would require one!

The code detects _careless_ non-conforming implementations. But that
goes for any strictly conforming code applied to any implementation
claiming conformance.

You say the code above requires a diagnostic... fine! My implementation
will issue a diagnostic. Now where's the conformance issue?
 
K

Keith Thompson

Peter Nilsson said:
[I think the intended example is really...

int8_t *ip = ...;
char *cp = ip;
]

Yes, thank you.
True, but any implementation can issue a diagnostic for any construct
whether it violates a constraint or not.

Sure, an implementation can issue a single meaningless diagnostic for
all translation units.
True, but there is nothing in the standard that says a given
implementation
_cannot_ issue a diagnostic in a circumstance that would require one!

The code detects _careless_ non-conforming implementations. But that
goes for any strictly conforming code applied to any implementation
claiming conformance.

You say the code above requires a diagnostic... fine! My implementation
will issue a diagnostic. Now where's the conformance issue?

There's none that I can see. But you're describing an implementation
that typedefs int8_t as plain char, then goes out of its way to hide
the fact that it's done so. As far as its behavior is concerned, you
might as well say that it typedefs int8_t as signed char (and issues
some annoying additional diagnostics). That doesn't strike me as
either useful or interesting.
 
P

Peter Nilsson

Keith said:
Peter Nilsson said:
Keith said:
...you can detect the non-conformance by the lack
of a diagnostic.

...there is nothing in the standard that says a given implementation
_cannot_ issue a diagnostic in a circumstance that would require one!

You say the [snipped] code above requires a diagnostic... fine! My
implementation will issue a diagnostic. Now where's the conformance
issue?

There's none that I can see. But you're describing an implementation
that typedefs int8_t as plain char, then goes out of its way to hide
the fact that it's done so. As far as its behavior is concerned, you
might as well say that it typedefs int8_t as signed char

That's the 'as if' rule in action.
(and issues some annoying additional diagnostics).

No, it issues the _required_ diagnostic, whether it's annoying or not.
That doesn't strike me as either useful or interesting.

The specific case in question isn't interesting because of its highly
contrived nature, but real implementations can and do go out of their
way _merely_ to satisfy conformance. Tedious required diagnostics are
just one example.
 
K

Keith Thompson

Peter Nilsson said:
Keith said:
Peter Nilsson said:
Keith Thompson wrote:
...you can detect the non-conformance by the lack
of a diagnostic.

...there is nothing in the standard that says a given implementation
_cannot_ issue a diagnostic in a circumstance that would require one!

You say the [snipped] code above requires a diagnostic... fine! My
implementation will issue a diagnostic. Now where's the conformance
issue?

There's none that I can see. But you're describing an implementation
that typedefs int8_t as plain char, then goes out of its way to hide
the fact that it's done so. As far as its behavior is concerned, you
might as well say that it typedefs int8_t as signed char

That's the 'as if' rule in action.

Not really.

Strictly speaking, the "as if" rule has to do with expression
evaluation. In the C99 standard, the index entry for "as-if rule"
points to 5.1.2.3, Program execution, which says:

In the abstract machine, all expressions are evaluated as
specified by the semantics. An actual implementation need not
evaluate part of an expression if it can deduce that its value is
not used and that no needed side effects are produced (including
any caused by calling a function or accessing a volatile object).
No, it issues the _required_ diagnostic, whether it's annoying or not.

I'm starting to lose track of what we're talking about. Let me try to
summarize.

The standard requires int8_t to be a typedef for a signed integer type
with width 8 (and a couple of other characteristics). Since plain
char is not a "signed integer type" even if it happens to be signed
(see 6.2.5), int8_t cannot legally be a typedef for plain char.
Either it's a typedef for signed char (if CHAR_BIT==8), or it's a
typedef for and extended signed integer type with the required
properties, or int8_t is not defined.

For any implementation, the following is a constraint violation
requiring a diagnostic:

char *cptr = 0;
int8_t *iptr = cptr; /* incompatible types */

An implementation that makes int8_t a typedef for plain char (which
we'll assume is signed) but is otherwise conforming most likely would
not issue a diagnostic for the initialization of iptr; because of
this, we can tell that the implementation is not conforming.

An implementation that makes int8_t a typedef for plain char but then
contrives to appear to be conforming anyway would have to issue the
required diagnostic for the initialization of iptr. Unless the
implementer is exceedingly clever and has way too much time on his
hands, it would probably also issue annoying diagnostics for
constructs that don't require them. For example:

typedef char plain_char;
char *cptr = 0;
plain_char *pcptr = cptr; /* annoying diagnostic (?) */

Spurious diagnostic like this don't make the implementation
non-conforming, of course. But if the implementer were sane, he would
simply make int8_t a typedef for signed char as soon as he realized
that making it a typedef for char is not allowed.
The specific case in question isn't interesting because of its highly
contrived nature, but real implementations can and do go out of their
way _merely_ to satisfy conformance. Tedious required diagnostics are
just one example.

Do you have some examples in mind? Satisfying comformance isn't
"mere" in my opinion; it's what implementations are supposed to do,
just as writers of application software can and do go out of their way
_merely_ to produce correct output. As for diagnostics, I've found
that the ones required by the C standard are insufficient -- which is
why good compilers and related tools produce additional non-required
diagnostics.

I'm trying to understand just what your point is. Can you summarize
it in a few sentences?
 
P

Peter Nilsson

Keith said:
Peter Nilsson said:
Keith said:
Keith Thompson wrote:
...you can detect the non-conformance by the lack
of a diagnostic.

...there is nothing in the standard that says a given implementation
_cannot_ issue a diagnostic in a circumstance that would require one!

You say the [snipped] code above requires a diagnostic... fine! My
implementation will issue a diagnostic. Now where's the conformance
issue?

There's none that I can see. But you're describing an implementation
that typedefs int8_t as plain char, then goes out of its way to hide
the fact that it's done so. As far as its behavior is concerned, you
might as well say that it typedefs int8_t as signed char

That's the 'as if' rule in action.

Not really.

Strictly speaking, the "as if" rule has to do with expression
evaluation. In the C99 standard, the index entry for "as-if rule"
points to 5.1.2.3, ...

Okay, I was speaking about the rule in a broader sense that C is
an abstract language.
I'm starting to lose track of what we're talking about. Let me try to
summarize. ...

We're on the same wavelength, it's just that you seem to see a
difference between a conforming implementation and a 'contrived'
conforming implementation.
Do you have some examples in mind?

Lots. There are plenty of extensions that require diagnostics on a
conforming implementation, e.g. long long under C90.

On most implementations, specific required diagnostics are often
suppressed unless the implementation is invoked in conforming mode.
In many such cases, the implementation has to perform additional
work to detect and diagnose the constraint violation.

Another example: many implementations that I've used won't diagnose...

unsigned char *foo = 0xFFFE;

....unless they are told to. Such definitions are part of the context
free portion of the grammar, and irrespective of the constraint
violation, an implementation must define semantics for the conversion
involved. So, detecting and issuing a diagnostic is just extra work
that an implementation will do if it wishes to claim conformance.
That extra work doesn't add to the capabilities of the
implementation beyond conformance.
Satisfying comformance isn't "mere" in my opinion;

Of course it isn't. I am focussing on diagnostics. The core job of
an implementation is to translate correct source into efficient code.
Diagnostics may be value adding and best practice, but they don't
change the semantics of the language.
I'm trying to understand just what your point is. Can you
summarize it in a few sentences?

You seem to understand my points just fine, we just differ in personal
emphasis.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,167
Messages
2,570,911
Members
47,453
Latest member
MadelinePh

Latest Threads

Top