4

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?

Pavneet_Singh
  • 36,884
  • 5
  • 53
  • 68
pistach
  • 391
  • 1
  • 4
  • 19
  • 8
    See [Breaking Changes in Visual C++ 2015](https://msdn.microsoft.com/en-us/library/bb531344.aspx), specifically the section " and " – Cody Gray - on strike Aug 09 '16 at 12:20
  • 1
    Some code please, so that we can guide you in right direction. – Ajay Aug 09 '16 at 12:20
  • Do you have an example of a `printf()`-call that triggers this? It sounds like you are causing undefined behavior. – EOF Aug 09 '16 at 12:21
  • 2
    Suggest you show a minimal, complete example of your code that is exhibiting this behaviour. Newer compilers can have better/more warnings. It may be your code always had problems but are now flagged by the newer compiler. Hence please show your code. – kaylum Aug 09 '16 at 12:22
  • 4
    And did you count the arguments for the printf calls in question VS2015 complains about? Is the number correct? Or did the new C4474 just pointed you to bugs undiscovered until now? ;-) – alk Aug 09 '16 at 13:33
  • 1
    This looks like a potentially good question that might help people migrating to VS2015 but it lacks information. Please provide an [MVCE](http://stackoverflow.com/help/mcve) – Teivaz Aug 09 '16 at 13:34
  • 1
    Agree with @isanae. This is a fine and possibly useful question, now that sample code has been added. (Most of the close votes accumulated before it was added.) Thank you for doing that; I have voted to reopen and edited to reinforce the quality. – Cody Gray - on strike Aug 09 '16 at 22:13
  • Thanks for editing my question. English isn't my native language. Finding the right words is sometimes difficult. – pistach Aug 10 '16 at 06:44
  • 1
    @pistach It's a bad edit with lots of typos. It made the post a lot worse. – isanae Aug 10 '16 at 17:10

1 Answers1

7

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.

isanae
  • 3,253
  • 1
  • 22
  • 47
  • 1
    Visual Studios' `/Wall` is not the same as `-Wall` in gcc and clang. It's use is [unrealistic in a real-world project](http://stackoverflow.com/questions/4001736/whats-up-with-the-thousands-of-warnings-in-standard-headers-in-msvc-wall) and is [discouraged by microsoft themselves](https://blogs.msdn.microsoft.com/vcblog/2010/12/14/off-by-default-compiler-warnings-in-visual-c/) – Ivan Aksamentov - Drop Aug 10 '16 at 00:17
  • @Drop You misread. The msdn blog link says to use `pragma warning` to disable noisy warnings and then "Turn on the /Wall switch for your codebase". I *always* turn it on in *all* my projects and use my own `push_warnings.h` and `pop_warnings.h` around third-party headers. I've implemented them in clang, gcc and visual c++. Works like a charm. – isanae Aug 10 '16 at 00:21
  • @isanae this is almost the same answer as i proposed with modifications in edit. – Pavneet_Singh Aug 10 '16 at 05:59
  • Turning on all warnings results in over 12000 warnings. (I didn't write this code, I only have to make some modifications to it). So this isn't an option for me. I will solve all these warnings. Thanks for pointing out "format specifier checking" was added in VS2015. – pistach Aug 10 '16 at 06:46
  • 1
    @PavneetSingh but with more information and less grammar problems – isanae Aug 10 '16 at 17:12
  • @isanae by that you mean the log output.great because i love cats – Pavneet_Singh Aug 10 '16 at 18:15