Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
248 views
in Technique[技术] by (71.8m points)

c - Format specifier for unsigned char

Say I want to print unsigned char:

unsigned char x = 12;

which is correct. This:

printf("%d",x);

or this:

printf("%u",x);

?

The thing is elsewhere on SO I encountered such discussion:

-Even with ch changed to unsigned char, the behavior of the code is not defined by the C standard. This is because the unsigned char is promoted to an int (in normal C implementations), so an int is passed to printf for the specifier %u. However, %u expects an unsigned int, so the types do not match, and the C standard does not define the behavior

-Your comment is incorrect. The C11 standard states that the conversion specifier must be of the same type as the function argument itself, not the promoted type. This point is also specifically addressed in the description of the hh length modifier: "the argument will have been promoted according to the integer promotions, but its value shall be converted to signed char or unsigned char before printing"

So which is correct? Any reliable source saying on this matter? (In that sense we should also print unsigned short int with %d because it can be promoted to int?).

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The correct one is*:

printf("%d",x);

This is because of default argument promotions as printf() is variadic function. This means that unsigned char value is always promoted to int.

From N1570 (C11 draft) 6.5.2.2/6 Function calls (emphasis mine going forward):

If the expression that denotes the called function has a type that does not include a prototype, the integer promotions are performed on each argument, and arguments that have type float are promoted to double. These are called the default argument promotions.

and 6.5.2.2/7 subclause tells:

The ellipsis notation in a function prototype declarator causes argument type conversion to stop after the last declared parameter. The default argument promotions are performed on trailing arguments.

These integer promotions are defined in 6.3.1.1/2 Boolean, characters, and integers:

If an int can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions.58) All other types are unchanged by the integer promotions.

This quote answers your second question of unsigned short (see comment below).


* with exception to more than 8 bits unsigned char (e.g. it might occupy 16 bit), see @chux's answer.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

56.9k users

...