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
intcan 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
llength modifier is present, theintargument 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, becausecharhas 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?