1

Consider the following code sample:

#define STRING_LITERAL  "%u, %u"
const char string_const[ ] = "%u, %u";

snprintf(dest_buff, sizeof(dest_buff), STRING_LITERAL, arg1, arg2, arg3);

My compiler then issues a Warning: the format string ends before this argument

Now if I change the instruction to:

snprintf(dest_buff, sizeof(dest_buff), string_const, arg1, arg2, arg3);

Then no warning is issued by the compiler.

My question is: does such a behavior comply with the C99 standard?

MD XF
  • 7,860
  • 7
  • 40
  • 71
MFM
  • 91
  • 1
  • 8
  • 1
    Does C99 require conforming compilers to issue the warning on invalid printf() calls (or any other variadic calls) at all? – user3125367 Apr 22 '15 at 10:09

5 Answers5

1

My question is: does such a behavior comply with C99 standard?

Both examples invoke undefined behavior but there is no violation of constraint or syntax rule, so no diagnostic is required.

ouah
  • 142,963
  • 15
  • 272
  • 331
1

The warning is generated by the compiler which was able to determine that you passed incorrect arguments to the call, and didn't in the second.

The standard defines that passing incorrect arguments and/or using incorrect flags results in undefined behavior.

The warning is not required by the Standard, and it is merely additional help to the programmer.

2501
  • 25,460
  • 4
  • 47
  • 87
0

You have too many arguments, should be either:

#define STRING_LITERAL  "%u, %u"
snprintf(dest_buff, sizeof(dest_buff), STRING_LITERAL, arg1, arg2);

or:

#define STRING_LITERAL  "%u, %u, %u"
snprintf(dest_buff, sizeof(dest_buff), STRING_LITERAL, arg1, arg2, arg3);

The reason for the lack of warning is that it is undefined behavior and the warning is only issued when the compiler is smart enough to think that something is wrong. If the string is directly in the snprintf command, the compiler is seemingly smart enough, if the string is passed indirectly it seemingly is not.

Roland Seuhs
  • 1,878
  • 4
  • 27
  • 51
0

In this example

snprintf(dest_buff, sizeof(dest_buff), STRING_LITERAL, arg1, arg2, arg3);

you're passing a string literal directly, while in this one

snprintf(dest_buff, sizeof(dest_buff), string_const, arg1, arg2, arg3);

you're passing a variable.

I'm assuming your compiler (whatever one that is) treats literals differently from variables for the purposes of the warning in question.

Andrew Henle
  • 32,625
  • 3
  • 24
  • 56
0

I've found the following statement in Annex I (Common warnings) of the C99 standard, that clarifies the situation.

1 An implementation may generate warnings in many situations, none of which are specified as part of this International Standard. The following are a few of the more common situations.

MFM
  • 91
  • 1
  • 8