4

The C99 standard talks about doubles in the specification for fprintf (which subsequently applies to printf). It says "a double argument representing a floating-point number is converted..." Then in paragraph 9, it says:

If a conversion specification is invalid, the behavior is undefined. If any argument is not the correct type for the corresponding specification, the behavior is undefined.

So I would expect the following to be undefined behavior but my compiler doesn't warn about it.

double d = 2.0;
float f = 2.0f;
printf("%f", d);
printf("%f", f); // here

On the other hand, the specification for fscanf says "floating point number" instead of double. Is it undefined behavior like this user claims?

  • 4
    Floats in C are automatically promoted to `double`, which is why the spec talks about doubles, but not about `float` – Icemanind Dec 15 '14 at 23:39
  • I would think there is a "conversion specification" for the type conversion from `float` to `double`, hence making `printf` expect a `double` but being passed a `float` fine, as `float can be implicitly converted to `double`. – bitmask Dec 15 '14 at 23:41
  • The [user](https://stackoverflow.com/questions/27487775/inverse-of-snprintf/27487797#comment43408227_27487797) claim about UB relates to `scanf()`. – chux - Reinstate Monica Dec 15 '14 at 23:42
  • 1
    possible duplicate of [C/C++ variadic functions and default promotions](http://stackoverflow.com/questions/22844360/c-c-variadic-functions-and-default-promotions) – Deduplicator Dec 15 '14 at 23:44
  • 1
    @chux - Since `scanf` is a pointer, it doesn't promote a pointer to a `float` to a pointer to a `double`. – Icemanind Dec 15 '14 at 23:44
  • @icemanind `scanf()` is not a pointer, but a function. And why comment about the obvious? – chux - Reinstate Monica Dec 15 '14 at 23:51
  • @chux - scanf() is a function that expects a pointer as one of its parameters. And it isn't obvious to the OP apparently, because he asked the question as to why. – Icemanind Dec 15 '14 at 23:54
  • @icemanind Then address the comment to the OP, not to me. – chux - Reinstate Monica Dec 15 '14 at 23:56
  • this line: printf("%f", d); is the actual problem as a double value would need to be downgraded to float for a printf to be always successful. That is not how things work, variables are promoted, not downgraded. writing: printf("%lf",d); would be correct. there is nothing wrong with the second call to printf – user3629249 Dec 16 '14 at 12:56
  • http://stackoverflow.com/questions/8559198/why-does-printf-implicit-loat-to-int-conversion-not-work , http://stackoverflow.com/questions/8303673/why-cast-is-needed-in-printf – Ciro Santilli OurBigBook.com Jun 02 '15 at 03:48
  • @Deduplicator You should focus more on making every body understand the answer . Rather than just going everywhere and finding duplicate. Even the co-founder of stackoverflow said duplicates are good . It increase site traffic. Also this is not really a duplicate. – Suraj Jain Aug 22 '16 at 20:09
  • @SurajJain He only said *some duplication is good*. This duplication though plainly isn't. The answer on the dupe, though short, might be more than the absolute minimum, but that doesn't mean it isn't a dupe. – Deduplicator Aug 22 '16 at 20:18

2 Answers2

6

Passing a float to printf is not undefined behavior--it's simply an impossibility. The float will be promoted to double before printf receives it.

scanf is different because what you're (at least normally) passing to scanf are pointers rather than the data objects themselves. Since you're passing a pointer to the original data, with scanf you need to distinguish between a float and a double.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
4

float in vararg functions are always promoted to double.

scanf deals with pointers.

lhf
  • 70,581
  • 9
  • 108
  • 149