4

As of the printf function is concerned, I understand the following from few references and experiments.

  • When we try to print an integer value with format specifiers that are used for float (or) double and vice the versa the behaviour is unpredictable.
  • But it is possible to use %c to print the character equivalent of the integer value. Also using of %d to print ASCII value (integer representations) of character is acceptable.

Similarly, what is the behaviour of scanf, if there is a mismatch of format specifier and the arguements passed to scanf. Does the standards define it?

Vivek Maran
  • 2,533
  • 5
  • 35
  • 50

1 Answers1

4

Variadic arguments (those matching the ellipsis, ...) are default-promoted. That means that all shorter integral types are promoted to int (or unsigned, as appropriate). There's no difference between inte­gers and characters (I believe). The difference between %d and %c in printf is merely how the value is formatted.

scanf is a different kettle of fish. All the arguments you pass are pointers. There's no default-pro­mo­tion among pointers, and it is crucial that you pass the exact format specifier that matches the type of the pointee.

In either case, if your format specifier doesn't match the supplied argument (e.g. passing an int * to a %p in printf), the result is undefined behaviour, which is far worse than being "unpredictable" -- it means your program is simply ill-formed.

Community
  • 1
  • 1
Kerrek SB
  • 447,451
  • 88
  • 851
  • 1,056
  • 2
    I'm not sure that "ill-formed" is the best way to describe it. If the behavior is undefined, your program is basically incorrect, but the implementation isn't required to warn you about it. – Keith Thompson Oct 10 '12 at 23:50
  • “passing an `int*` to a `%p` in printf()” is perhaps not the most didactic example, since so many C programmers think that it is correct. It might be better to use a more obviously wrong example first (e.g. `int*` to `%f`) and then perhaps include the information that passing `int*` to `%p` is technically incorrect as well. – Pascal Cuoq Aug 30 '13 at 12:59
  • @PascalCuoq: Hm, I thought it was didactic precisely *because* many people think -- erroneously -- that this is correct. – Kerrek SB Aug 30 '13 at 13:32
  • 1
    @KerrekSB It is your answer. This was only a suggestion. To put it differently, I think your answer is great for developers who already know that `void*` and `int*` are incompatible, and confusing for the others. – Pascal Cuoq Aug 30 '13 at 16:23
  • @KerrekSB, could you supply a standard reference? I am particularly interested in passing `int` to `%c`. Is that an UB? –  Nov 18 '16 at 20:38
  • @Arkadiy: C11 7.21.6.1p9: "If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined." – Kerrek SB Nov 18 '16 at 20:41