C++编译器关于警告的改进

[原文发表地址]Improvements to Warnings in the C++ Compiler

[原文发表时间] 2014/11/12 3:35PM

    在vs2015 Preview版本中,对于C++编译时出现的警告,我们做了大量的改善。

    Printf系列函数

     C++社区已经声明,printf 以及其他的输出函数仍然被大量使用,并且将会提供更加严密的判断。在VS2015 Preview版本中,编译器将会通过格式行来检查你提供的参数的数目是否和函数期望的参数个数一致。例如:

  printf("%d %d\n", 1); //C4317
 printf("%d\n", 1, 2); //C4422 

编译器将会报出如下:

  warning C4317: 'printf' : not enough arguments passed for format string 
 warning C4422: 'printf' : too many arguments passed for format string

更进一步,如果使用了一些不允许用于printf变量中的说明符,这时编译器将会报告如下的警告,例如:

   int n;    printf_s("Test %n", &n); //C4426

在这里,printf_s 是printf的增强安全版本,而这是不允许%n说明符的,因此警告如下:

warning C4426: '%n' is not allowed in the format string of function 'printf_s'.

在VS2015 RTW中,我们将会增加一些警告,这些警告也是用来检查参数类型是否和函数的需要的类型一致。

    隐藏变量

    如果在这个作用域中已经包含了一个和这个变量同名的变量,那么这个变量声明将会被隐藏,例如:

  void f(int x) 
 { 
 int y;
 { 
 char x; //C4457
 char y; //C4456
 } 
 }
  内部声明的变量x覆盖了函数f的形参x,因此编辑器将会报出如下警告:
 warning C4457: declaration of 'x' hides function parameter

  内部声明的变量y覆盖了在函数域中声明的y,因此编译器将报出警告:

 warning C4456: declaration of 'y' hides previous local declaration

    注意:和以前一样,声明了一个和函数的参数名字相同但不附属于内部域的变量会触发错误,例如:

  void f(int x) 
 { 
 char x; //C2082
 }

    编译器将报出:

  error C2082: redefinition of formal parameter 'x'

旧代码?     

        如果你用/WX , 这些新的警告将导致你原来的工程无法正常构建,为了解决这个问题,你可以用#pragma warning 或者/WD编译选项去避免它, 另外,为了加快你不愿意修改的那部分代码的汇编, 你可以增加一个新的编译选项,这个选项可以允许你控制由编译器报出的所有的警告。

       比如说, 为了禁止由XX.YY.ZZZZ之后的编译版本引入的警报,用use /Wv: XX.YY.ZZZZ来进行编译, 其中XX编译器版本号的关键数字,比如:15 是Visual Studio 2008的关键数字, 16是Visual Studio 2010的关键数字,17是Visual Studio 2012以及18 是 Visual Studio 2013的关键数字

       然而,对于仍然处于开发中的工程而言,我们强烈鼓励你保留这些新的警告并且去修改你的代码。因为它们很有可能帮助你写出更加强健和安全的代码。

 

公告