Note: The suggested duplicate deals with unsigned int
and signed int
, not unsigned char
and signed char
. The suggested duplicate question deals with C11. This question is concerned with C89 only. Can this question be reopened?
My code:
#include <stdio.h>
int main()
{
signed char c;
unsigned char d;
c = (signed char) -2;
d = (unsigned char) c;
printf("%d %d\n", c, d);
d = (unsigned char) 254;
c = (signed char) d;
printf("%d %d\n", c, d);
return 0;
}
Output:
$ clang -Wall -Wextra -pedantic -std=c89 foo.c && ./a.out
-2 254
-2 254
Is the output guaranteed to be -2 254
in a standard-conforming C89 compiler for both conversions shown above? Or is the output dependent on the implementation?
Is converting from
unsigned char
tosigned char
and vice versa in C89 well defined?
Conversions to unsigned types is well defined. To signed types has implementation details.
Is the output guaranteed to be -2 254 in a standard-conforming C89 compiler for both conversions shown above?
No.
Or is the output dependent on the implementation?
Yes.
Not all implementations use 8-bit char
and conversions to signed types incur implementation details.
Spec details: C89 Conversions. This wording differs from recent C specs. I have not found a significant difference.
When UCHAR_MAX <= INT_MAX
, code could use below and let the compiler emit optimized, well defined code.
c = (signed char) (d > SCHAR_MAX ? d - UCHAR_MAX - 1 : d);
Likely needs some more thought to cover all cases.