Is the following code undefined behavior according to GCC in C99 mode:
signed char c = CHAR_MAX; // assume CHAR_MAX < INT_MAX
c = c + 1;
printf("%d", c);
Is the following code undefined behavior according to GCC in C99 mode:
signed char c = CHAR_MAX; // assume CHAR_MAX < INT_MAX
c = c + 1;
printf("%d", c);
signed char
overflow does cause undefined behavior, but that is not what happens in the posted code.
With c = c + 1
, the integer promotions are performed before the addition, so c
is promoted to int
in the expression on the right. Since 128
is less than INT_MAX
, this addition occurs without incident. Note that char
is typically narrower than int
, but on rare systems char
and int
may be the same width. In either case a char
is promoted to int
in arithmetic expressions.
When the assignment to c
is then made, if plain char
is unsigned
on the system in question, the result of the addition is less than UCHAR_MAX
(which must be at least 255) and this value remains unchanged in the conversion and assignment to c
.
If instead plain char
is signed
, the result of the addition is converted to a signed char
value before assignment. Here, if the result of the addition can't be represented in a signed char
the conversion "is implementation-defined, or an implementation-defined signal is raised," according to §6.3.1.3/3 of the Standard. SCHAR_MAX
must be at least 127, and if this is the case then the behavior is implementation-defined for the values in the posted code when plain char
is signed
.
The behavior is not undefined for the code in question, but is implementation-defined.
No, it has implementation-defined behavior, either storing an implementation-defined result or possibly raising a signal.
Firstly, the usual arithmetic conversions are applied to the operands. This converts the operands to type int
and so the computation is performed in type int
. The result value 128
is guaranteed to be representable in int
, since INT_MAX
is guaranteed to be at least 32767 (5.2.4.2.1 Sizes of integer types), so next a value 128
in type int
must be converted to type char
to be stored in c
. If char
is unsigned, CHAR_MAX
is guaranteed to be at least 255; otherwise, if SCHAR_MAX
takes its minimal value of 127:
6.3.1.3 Signed and unsigned integers
When a value with integer type is converted to another integer type, [if] the new type is signed and the value cannot be represented in it[,] either the result is implementation-defined or an implementation-defined signal is raised.
In particular, gcc can be configured to treat char
as either signed or unsigned (-f\[un\]signed-char
); by default it will pick the appropriate configuration for the target platform ABI, if any. If a signed char is selected, all current gcc target platforms that I am aware of have an 8-bit byte (some obsolete targets such as AT&T DSP1600 had a 16-bit byte), so it will have range [-128, 127]
(8-bit, two's complement) and gcc will apply modulo arithmetic yielding -128
as the result:
The result of, or the signal raised by, converting an integer to a signed integer type when the value cannot be represented in an object of that type (C90 6.2.1.2, C99 and C11 6.3.1.3).For conversion to a type of width N, the value is reduced modulo 2^N to be within range of the type; no signal is raised.