pistach pistach - 3 months ago 20
C Question

Calls to printf-style functions result in a warning after upgrading to Visual Studio 2015

Calling

fprintf
function producing warnings.
In Visual Studio 2013, everything compiled and worked fine without errors and warnings.

Now the project has been migrated to Visual Studio 2015 (without any changes). At compile time, I am getting this warning
C4474 : too many arguments passed for format string
on most of my
fprintf
-calls.

Most of these warnings point to the following line of code:

fprintf (stderr,"Missing header file name. Formant is :\n", pArg);


How can i solve this problem ? what modification do i need to make to remove these warnings , or is this something irrelevant that can be ignored with modification in project settings ?




I see that in this MSDN-article there's a change mentioned to these functions.


The definitions of all of the printf and scanf functions have been moved inline into stdio.h, conio.h, and other CRT headers.


Is this required any fix ? or Is this just a harmless change in VS 2015 ?
Does this mean , there a potentially crash-inducing pitfall here, too?

Answer

Visual C++ 2015 introduced "format specifiers checking". The compiler can detect some problems at compile-time and generate warnings. Prior to 2015, a mismatch between the format string and the arguments would not generate any diagnostic, either at compile-time or run-time (unless the problem was serious enough to make the program crash).

The code you show has an extra argument pArg that won't be used by fprintf() because there is no placeholder in the format string.

You will have to go through every single warning and fix them. Don't ignore them. They may indicate a harmless problem or a serious bug. Note that some of the warnings are only visible with /W4. You should always be using /Wall anyways.

Here's a few examples:

void f()
{
    printf("hello, world", 42);   // line 8:  no %d in format string
    printf("missing %d");         // line 9:  missing argument for %d
    printf("wrong type %f", 3);   // line 10: wrong argument type
}

These are the warnings generated with cl /Wall:

a.cpp(8): warning C4474: 'printf' : too many arguments passed for format string
a.cpp(8): note: placeholders and their parameters expect 0 variadic arguments,
             but 1 were provided
a.cpp(9): warning C4473: 'printf' : not enough arguments passed for format string
a.cpp(9): note: placeholders and their parameters expect 1 variadic arguments,
             but 0 were provided
a.cpp(9): note: the missing variadic argument 1 is required by format string '%d'
a.cpp(10): warning C4477: 'printf' : format string '%f' requires an argument of
             type 'double', but variadic argument 1 has type 'int'

Note that gcc has had an equivalent -wformat since 3.0.