Do I understand the standard correctly that this program cause UB:
#include <stdio.h>
int main(void)
{
char a = 'A';
printf("%c\n", a);
return 0;
}
When it is executed on a system where sizeof(int)==1 && CHAR_MIN==0
?
Because if a
is unsigned and has the same size (1) as an int
, it will be promoted to an unsigned int
[1] (2), and not to an int
, since a int
can not represent all values of a char
. The format specifier "%c"
expects an int
[2] and using the wrong signedness in printf()
causes UB [3].
Relevant quotes from ISO/IEC 9899 for C99
[1] Promotion to int
according to C99 6.3.1.1:2:
If an
int
can represent all values of the original type, the value is converted to anint
; otherwise, it is converted to anunsigned int
. These are called the integer promotions. All other types are unchanged by the integer promotions.
[2] The format specifier "%c"
expects an int
argument, C99 7.19.6.1:8 c
:
If no
l
length modifier is present, theint
argument is converted to anunsigned char
, and the resulting character is written.
[3] Using the wrong type in fprintf()
(3), including wrong signedness, causes UB according to C99 7.19.6.1:9:
... If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.
The exception for same type with different signedness is given for the va_arg
macro but not for printf()
and there is no requirement that printf()
uses va_arg
(4).
Footnotes: (marked with (n))
This implies
INT_MAX==SCHAR_MAX
, becausechar
has no padding.See also this question: Is unsigned char always promoted to int?
The same rules are applied to
printf()
, see C99 7.19.6.3:2See also this question: Does printf("%x",1) invoke undefined behavior?