tags:

views:

3752

answers:

4

Why is it that scanf() needs the L in "%lf" when reading a double, when printf() can use "%f" regardless of whether its argument is a double or a regular-precision float?

Example code:

double d;
scanf("%lf", &d);
printf ("%f", d);
+26  A: 

Because C will promote floats to doubles for functions that take variable arguments. Pointers aren't promoted to anything, so you should be using %lf or %g to read in doubles.

MSN

MSN
Default argument promotions are standard C, not just MSVC.
Robert Gamble
Fixed as per your comment. YAY!
MSN
+1 for being exactly right. IMHO, it shows that scanf() is a hideous function which you should only tolerate if there is no alternative. It is far too easy to introduce insidious defects by passing pointers to the wrong sort of data, and of course there is no type checking on the parameters you pass to it.
AAT
+4  A: 

scanf needs to know the size of the data being pointed at by &d to fill it properly, whereas variadic functions promote floats to doubles (not entirely sure why), so printf is always getting a double.

Tanktalus
+1  A: 

Using either a float or a double value in a C expression will result in a value that is a double anyway, so printf can't tell the difference. Whereas a pointer to a double has to be explicitly signalled to scanf as distinct from a pointer to float, because what the pointer points to is what matters.

fcw
float is converted to a double *in this case* because the arguments are part of a variable-length argument list, floats are not always converted to doubles in C.
Robert Gamble
+2  A: 

Because otherwise scanf will think you are passing a pointer to a float which is a smaller size than a double, and it will return an incorrect value.

Jim Buck