pistach pistach - 3 months ago 27
C Question

Calls to printf-style functions result in warnings after migrating from Visual Studio 2013 to Visual Studio 2015

I have a program that calls

fprintf
. In Visual Studio 2013, everything compiled and executed without errors and warnings. Now the project has been migrated to Visual Studio 2015 (without any changes) and I am getting the following warning on most of my
fprintf
calls:

C4474: too many arguments passed for format string


Most of these warnings are pointing to the following line of code:

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


How can I solve this problem? Do I need to rewrite my code or is there something wrong with my project settings that is causing these warnings?




I see that, in this MSDN article there were changes made 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 relevant to my problem? Is this just a harmless change in VS 2015 or is 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.

Comments