【问题标题】:Calls to printf-style functions result in warnings after migrating from Visual Studio 2013 to Visual Studio 2015从 Visual Studio 2013 迁移到 Visual Studio 2015 后,调用 printf 样式函数会导致警告
【发布时间】:2016-08-09 12:18:34
【问题描述】:

我有一个调用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 中的一个无害更改,还是这里也存在潜在的崩溃陷阱?

【问题讨论】:

  • 参见Breaking Changes in Visual C++ 2015,特别是“”部分
  • 请提供一些代码,以便我们指导您正确的方向。
  • 建议您展示一个显示此行为的代码的最小、完整示例。较新的编译器可以有更好/更多的警告。可能是您的代码总是有问题,但现在被较新的编译器标记。因此,请显示您的代码。
  • 您是否计算过 VS2015 抱怨的 printf 调用的参数?号码是否正确?还是新的 C4474 只是为您指出了迄今为止尚未发现的错误? ;-)
  • 这看起来像是一个潜在的好问题,可能会帮助人们迁移到 VS2015,但它缺乏信息。请提供MVCE

标签: c++ c visual-studio visual-studio-2015 printf


【解决方案1】:

Visual C++ 2015 引入了"format specifiers checking"。编译器可以在编译时检测到一些问题并生成警告。在 2015 年之前,格式字符串和参数之间的不匹配不会在编译时或运行时生成任何诊断信息(除非问题严重到足以导致程序崩溃)。

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

您必须检查每一个警告并修复它们。 不要忽视它们。它们可能表示无害的问题或严重的错误。请注意,某些警告仅对/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 有一个等效的 -wformat since 3.0

【讨论】:

  • Visual Studios 的 /Wall 与 gcc 和 clang 中的 -Wall 不同。它的用途是unrealistic in a real-world projectdiscouraged by microsoft themselves
  • @Drop 你误读了。 msdn 博客链接说要使用 pragma warning 禁用嘈杂的警告,然后“为您的代码库打开 /Wall 开关”。我总是在我的所有项目中打开它,并在第三方标题周围使用我自己的push_warnings.hpop_warnings.h。我已经在 clang、gcc 和 visual c++ 中实现了它们。像魅力一样工作。
  • @isanae 这与我在编辑中提出的修改几乎相同。
  • 开启所有警告会导致超过 12000 个警告。 (这段代码不是我写的,我只需要对其进行一些修改)。所以这对我来说不是一个选择。我会解决所有这些警告。感谢您指出 VS2015 中添加了“格式说明符检查”。
  • @PavneetSingh,但信息更多,语法问题更少
猜你喜欢
  • 1970-01-01
  • 2017-06-03
  • 1970-01-01
  • 1970-01-01
  • 2016-12-10
  • 1970-01-01
  • 2015-01-19
  • 2014-03-23
  • 1970-01-01
相关资源
最近更新 更多