tags:

views:

218

answers:

5
+1  Q: 

Is %d a cast in C?

int a;
printf("%d\n", a);

I wonder if %d is a cast?

+5  A: 

No, it is part of the format specifier string for printf() function's first argument; the format string. It will print out a decimal representation of that int you passed as the second argument.

Sean A.O. Harney
+5  A: 

It is not. It is just a "hint" for printf() function to treat the 'a' argument as an 'int'

Aleksei Potov
+5  A: 

In any case it won't be a cast but a reinterpretation (like getting the address, casting to a pointer of a different type and then getting the contents as a new type).

Example:

printf("%d\n", 1.5);

won't print integer 1, but the integer value of the representation of 1.5 in IEEE 754. If you want to cast, you must explicitly put (int) in front of the value.

fortran
how is 1.5 represent in IEEE 754?
tsubasa
Actually, as you invoke **Undefined Behavior**, it can do anything. It can print "forty two" or format your hard disk.
pmg
@pmg well, the behaviour is undefined but predictable... stranger things could be if you try to interpret a larger type as a smaller one, but a double (as 1.5) is at least as large as an int (in both 32 and 64 bit architectures, I dunno what will happen with the future ones).In this case, in my machine it prints just 0, because of the endiannes of the Intel, it takes the lower part of 1.5 that happens to be nil. In a big endian machine it would have printed "1073217536", I guess.
fortran
@tsubasa you can work it out yourself... first bit sign=0, next group of bits, exponent in excess representation (make it equal 0, for single precision it's a group of 8 bits set at 01111111, I cannot remember for double), and for the mantissa, the whole part is implicit, so we just have another bit set to 1 for the 0.5 decimal part, the rest to zero.
fortran
`1.5` as an IEEE-754 double has the representation `0x3ff8000000000000`. Assuming that your platform has 32-bit ints, the printf statement here will most likely produce either `0` or `1073217536`, depending on endianness.
Stephen Canon
Modern GNU libc can type-check format strings. I believe boost C++ libraries also provides safer printf family functions.
Sean A.O. Harney
A: 

No, it is a format specifier. It has semantic meaning only to the formatted I/O functions and is not part of the C language itself. You could equally write yopur own

All it does is specify the 'human readable' representation in which to present an int value; there is no type conversion or translation.

Clifford
+2  A: 

No, it's not a cast, but I suggest you take a look at the source for printf() to understand this. There's nothing special about printf() -- it's just a varargs function like any other. It's one of the first functions you learn in C, usually well before you learn varargs, so it often sticks out in people's minds as special when it's really not. A quick study of the source will probably be enlightening.

When you pass a format string to printf(), you're telling the function what to expect in its argument list (generally on the stack), but that might not agree with what you actually put there. With %d, you're telling printf() to take the next integer-sized chunk of bytes off the argument list and format those bytes as if they represent a signed decimal number. So when printf() parses the format string and encounters a %d, it will probably do something like:

int num = va_arg(args, int);

And then format and output the bytes in "num" as if they were an integer, regardless of what kind of argument you actually passed. If you put a float in the arguments where printf() is told to expect an integer, the output will be a decimal representation of the IEEE floating point bytes -- probably not what you intended, and not what a true cast would have done.

Casey Barker