Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I pass a char where an integer is expected in printf?

Is the following code correct?

char mychar = 200;
printf("%x", mychar);

According to http://www.cplusplus.com/reference/clibrary/cstdio/printf/ %x expects an integer (4 bytes with my compiler) and I only pass 1 byte here. Since printf makes use of varargs, my fear is that this only works because of byte alignment on the stack (i.e. a char always uses 4 bytes when pushed on the stack).

I think it would be better to write:

char mychar = 200;
printf("%x", static_cast<int>(mychar));

Do you think the first code is safe anyway? If not, do you think I could get a different output if I switch to a bigendian architecture?

like image 597
Emiliano Avatar asked Jul 11 '12 11:07

Emiliano


2 Answers

In your example, the argument is actually of type int. mychar is promoted to int due to the default argument promotions.

(C99, 6.5.2.2p6) "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 (emphasis mine):

(C99, 6.5.2.2p7) "If the expression that denotes the called function has a type that does include a prototype, the arguments are implicitly converted, as if by assignment, to the types of the corresponding parameters, taking the type of each parameter to be the unqualified version of its declared type. 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."

Note that technically the x conversion specifier requires an unsigned int argument but int and unsigned int types are guaranteed to have the same representation.

like image 72
ouah Avatar answered Oct 21 '22 22:10

ouah


This only works for you because your platform is able to interpret an int (to which your char is promoted) as an unsigned, this is what %x expects. To be sure that this always works you should use and appropriate format specifier, namely %d.

Since it seems that you want to use char as numerical quantity it would be better to use the two alternative types signed char or unsigned char to make your intention clear. char can be a signed or unsigned type on function of your platform. The correct specifier for unsigned char would then be %hhx.

like image 40
Jens Gustedt Avatar answered Oct 22 '22 00:10

Jens Gustedt