25

I wonder if this yields in undefined behaviour:

printf("Test %d %s", 123, "abc", "def", "ghi");

The first two arguments after the format string match the format string, so these are OK; but the 3rd and 4th arguments are in excess because there are no more corresponding format specifiers.

IMHO printf() should simply ignore these excess arguments and there should be no UB. Is this correct?

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
  • 1
    I think this question is like asking "Can a function that accepts varargs take any number of arguments?". The mechanism that allows the handling of a variable number of arguments works whatever the particulars of how the function uses those arguments... – SJuan76 Jul 22 '15 at 17:47

2 Answers2

39

Yes, this scenario is explicitly defined by the standard. It is not undefined behaviour.

To quote the C11 standard, chapter §7.21.6.1, The fprintf() function

[...] If the format is exhausted while arguments remain, the excess arguments are evaluated (as always) but are otherwise ignored [...]

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • 3
    +1, I wasn't aware that it is explicitly defined. BTW "not UB" can be optimized, the "not" and the "un" cancel out, remains "defined behavior". – Jens Gustedt Jul 22 '15 at 10:28
  • As someone who isn't familiar with the implementation of C: why evaluate leftover arguments? Assuming the original format string (first argument) is evaluated before the replacements, this seems like it could be optimized. – Jules Jul 22 '15 at 15:09
  • 5
    @JulesMazur Not evaluating arguments would mean that `printf("%d", ++i);` would increment `i`, while `printf("foo", ++i);` wouldn't. Which hardly makes any sense and is incredibly obscure. Hence, "as always", the arguments are evaluated before being passed in, then ignored by the function. – Quentin Jul 22 '15 at 15:16
  • 6
    @JulesMazur In addition to Quentin's point, arguments are always evaluated before being passed to functions. Making printf special in that regard would just make all our lives more complicated. – Chris Hayes Jul 22 '15 at 15:54
  • 4
    @JensGustedt - the term "undefined behavior" is defined by the standard; the term "defined behavior" is not. So the correct phrase is, indeed, "not undefined behavior". – Pete Becker Jul 22 '15 at 17:36
  • @PeteBecker, how would it define the term "defined"? By saying something like ``the terms "definition" in this International standard is defined to ...'' Have a look a the beginning of Section 3. "Terms, definitions, and symbols" and you see that *defining* things is all what this International Standard is about. And Section 4 says *Undefined behavior is otherwise indicated in this International Standard by the words ‘‘undefined behavior’’ or by the omission of any explicit definition of behavior.* – Jens Gustedt Jul 22 '15 at 20:21
  • 1
    @JensGustedt - having spent eight years as project editor for C++ I'm quite familiar with the structure of standards. The term you suggested, "defined behavior," is not a technical term in the standard. – Pete Becker Jul 23 '15 at 03:47
  • @PeteBecker, first I am talking of C and not C++, and then what do you think that the partial sentence *explicit definition of behavior* means (that I cited)? Definition of behavior, this is all what the standard is about. – Jens Gustedt Jul 23 '15 at 07:30
2

Basically, printf (or any formatting function) will look into only 'n' number of %d, %c, %f..., etc in the format string from the variable list argument. Others are simply ignored.

vivekn
  • 35
  • 6