tags:

views:

103

answers:

2

I wanted to ask whether the following statement where printf() has been provided with a type int where it expected a type char will invoke UNDEFINED BEHAVIOUR. If not, what exactly is the step will be taken to make it compatible with expected type. Will a be shortened to char type??

   int a = 65;   
   printf("%c", a);
A: 

Variable numbers of arguments

SUMMARY: In order to access the arguments within the called function, the functions declared in the header file must be included. This introduces a new type, called a va_list, and three functions that operate on objects of this type, called va_start, va_arg, and va_end.

#include <stdarg.h>
type va_arg(va_list ap, type);

Each call to this macro will extract the next argument from the argument list as a value of the specified type. The va_list argument must be the one initialized by va_start. If the next argument is not of the specified type, the behaviour is undefined.

The behaviour is also undefined if va_arg is called when there were no further arguments.

adatapost
doesn't apply here because of argument promotion
Christoph
This answer describes some of what goes on inside printf(); it does not explain why the call is OK.
Jonathan Leffler
+3  A: 

Variable arguments are subject to the default argument promotion, eg char will be promoted to int, float to double (that's the reason why you only have a single format specifier to print both single and double precision floating point values).

So passing an int instead of a char is perfectly valid and even desirable, as character literals are of type int anyway. According to the C99 spec, section 7.19.6.1 §8, on seeing the conversion specifier %c, printf() expects an argument of type int and will then go on and cast this value to unsigned char.

This means the following is guaranteed to output a, as conversion of signed to unsigned types is well-defined:

int a = 'a' + UCHAR_MAX + 1;
printf("%c", a);
Christoph
Shorter types get promoted to longer, not opposite. And where it is defined that character literals are ints, not chars ?
qrdl
@qrdl: ISO C99, section 6.4.4.4 §10: "An integer character constant has type int."; also, where did I say that a longer type gets promoted to a shorter?
Christoph
@Christoph Sorry, I'm wrong about single character literals. Multi-character literals are implementation-defined (as specified by C99 section 6.4.4.4), but single-character literals indeed are ints.I understood your statement "passing an int instead of a char is perfectly valid" as "int gets promoted to char", however in this context it didn't mean that, my bad.I'd write it differently - "on seeing %c printf() expects int and casts it to unsigned int, a specified by section 7.19.6.1 §8 of C99"
qrdl
@christopherthanks for ur reply .int a = 'a' + UCHAR_MAX + 1;can u explain the significance of the above statement!,will'nt the value of a will be this after ur assignement on a machine where the size of char is 1byte:256+65
mawia
@qrdl: clarified; @mawia: `a = 'a' + UCHAR_MAX + 1 = 97 + 255 + 1 = 353`; when converting to `unsigned char`, you'll get back the original value as `(unsigned char)353 = 353 % 256 = 97 = 'a'`
Christoph
@Cristoph: actually I don't think it's guaranteed to print 'a'. Suppose that int is the same size as char on your implementation. Then the addition overflows, and IIRC overflow of a signed integer is undefined behaviour. So it could print 'b'. Pretty unlikely implementation choice, of course, since sane processors tend to support arithmetic wraparound these days...
Steve Jessop
Of course if you're lucky it'll be a compiler warning ("constant expression overflows type", or something like that), but I don't think compilers are required to evaluate addition of constants before runtime.
Steve Jessop
@onebyone: nice catching that; yes, singned integer overflows are undefined, but it should work if you convert the character constant to `unsigned` and `UINT_MAX + 1` is a multiple of `UCHAR_MAX + 1`; adding this to the answer might only add confusion, so I think I'll leave it as-is
Christoph