从Visual Studio 2013迁移到Visual Studio 2015后,调用printf-style函数会导致警告

4
我有一个调用fprintf的程序。在Visual Studio 2013中,一切都编译并执行了,没有出现错误和警告。现在该项目已经迁移到Visual Studio 2015(没有任何更改),我大部分的fprintf调用都会出现以下警告:
C4474: too many arguments passed for format string

大多数警告都指向以下代码行:
fprintf (stderr,"Missing header file name. Formant is :\n", pArg);

我该如何解决这个问题?我需要重写代码还是我的项目设置有问题导致出现这些警告?

我看到在this MSDN文章中,这些函数已经进行了更改:

所有printf和scanf函数的定义都已内联到stdio.h、conio.h和其他CRT头文件中。

这与我的问题有关吗?这只是VS 2015中无害的更改,还是在这里存在潜在的崩溃陷阱?


8
请参阅Visual C++ 2015中的重大更改,特别是“<stdio.h>和<conio.h>”一节。 - Cody Gray
1
请提供一些代码,这样我们才能指导您朝正确的方向前进。 - Ajay
2
建议您展示一个最小化、完整的代码示例,以展示出现此行为的情况。新版本的编译器可能会有更好/更多的警告。也许您的代码一直存在问题,但现在被新版本的编译器标记出来了。因此,请展示您的代码。 - kaylum
4
你有没有计算问题中printf调用的参数数量?数量是否正确?还是新的C4474只是指向了直到现在才被发现的错误?;-) Translated: Have you calculated the number of arguments in the printf calls mentioned in the issue that VS2015 is complaining about? Is the number correct? Or did the new C4474 just reveal previously undiscovered bugs? ;-) - alk
1
同意@isanae的观点。现在已经添加了示例代码,这是一个不错且可能有用的问题。(大部分关闭投票都是在添加示例代码之前累积的。)感谢您的付出;我已经投票重新开放并进行了编辑以加强质量。 - Cody Gray
显示剩余4条评论
1个回答

7

Visual C++ 2015引入了"格式说明符检查"。编译器可以在编译时检测到一些问题并生成警告。在2015年之前,格式字符串和参数之间的不匹配不会生成任何诊断,无论是在编译时还是运行时(除非问题严重到足以使程序崩溃)。

您展示的代码有一个额外的参数pArg,因为格式字符串中没有占位符,所以fprintf()将不会使用它。

您需要逐个处理每个警告并进行修复。不要忽略它们。它们可能表示一个无害的问题或一个严重的错误。请注意,其中一些警告只能在使用/W4时可见。无论如何,您应该始终使用/Wall

以下是一些示例:

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
}

这些是使用 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'

请注意,gcc自3.0版本以来已经有了等效的-wformat

1
Visual Studios的/Wall与gcc和clang中的-Wall不同。在现实世界的项目中使用它是不切实际的,并且微软自己也不鼓励使用它。参考链接:https://dev59.com/4W865IYBdhLWcg3wEaUx 和 https://blogs.msdn.microsoft.com/vcblog/2010/12/14/off-by-default-compiler-warnings-in-visual-c/ - Ivan Aksamentov - Drop
@Drop 你看错了。msdn博客链接中说要使用 pragma warning 去禁用嘈杂的警告,然后“为你的代码库打开/Wall开关”。我在所有我的项目中都会打开它,并在第三方头文件周围使用自己的push_warnings.hpop_warnings.h。我已经在clang、gcc和Visual C++中实现了它们。效果非常好。 - isanae
@isanae 这个答案和我提出的基本相同,只是在编辑方面进行了修改。 - Pavneet_Singh
打开所有警告会导致超过12000个警告。(我没有编写这段代码,我只需要对其进行一些修改)。所以这对我来说不是一个选项。我将解决所有这些警告。感谢指出"格式说明符检查"在VS2015中被添加。 - pistach
1
@PavneetSingh,但需要更多的信息和更少的语法问题。 - isanae
@isanae 你的意思是日志输出吗?太好了,因为我喜欢猫。 - Pavneet_Singh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接