Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 该代码是否会导致警告_C++_Warnings_Static Analysis - Fatal编程技术网

C++ 该代码是否会导致警告

C++ 该代码是否会导致警告,c++,warnings,static-analysis,C++,Warnings,Static Analysis,我遇到了类似于下面的代码,它是合法的,尽管不是很聪明。范围内同一函数中同时具有相同名称的两个堆栈变量是合法的,但可能会导致问题。(阅读:我只是浪费了半个小时调试这个)。在VS2010上的警告级别4(最高级别),我希望它能够捕捉到这种情况。我是否遗漏了什么,或者是时候用lint重温一下整个代码库了?像lint这样的静态分析工具会发现这样的名称冲突吗 char *x = strchr(Buffer,' '); if (x) { *x = 0; x++;

我遇到了类似于下面的代码,它是合法的,尽管不是很聪明。范围内同一函数中同时具有相同名称的两个堆栈变量是合法的,但可能会导致问题。(阅读:我只是浪费了半个小时调试这个)。在VS2010上的警告级别4(最高级别),我希望它能够捕捉到这种情况。我是否遗漏了什么,或者是时候用lint重温一下整个代码库了?像lint这样的静态分析工具会发现这样的名称冲突吗

   char *x = strchr(Buffer,' ');
   if (x)
   {
     *x = 0;
     x++;
     char *x = strchr(x,' ') 
     if (x)
        *x = 0;
   }

编辑:我在写原始答案(如下)时没有注意到这一点。您发布的代码是非法的,并导致未定义的行为。令人不快的是:

char *x = strchr(x,' ');
在这里,
strchr
调用中的
x
不是指在封闭范围中定义的
x
,而是指先前在同一行中定义的
x
。因此,该行读取未初始化的变量,从而导致未定义的行为。从C++标准,

§3.3.2/1[基本范围pdecl]
名称的声明点在其完整声明人(第8条)之后和初始值设定人(如有)之前,除非下文另有说明。[示例:

   int x = 12;
   { int x = x; }
这里,第二个x用它自己的(不确定)值初始化。-结束示例]

如果下面示例中的对应行更改为

int x = 21 + x; // generates "warning: x is used uninitialized in this function"
在VS2012上复制您的
strchr
示例会生成此警告(位于
/W1
及以上位置):


原始答案如下(不完全准确):

代码没有什么违法的地方。您通过添加大括号引入了一个新的范围,并且允许您在新范围内定义变量,即使这些变量名以前已在封闭范围内定义

新定义之后对变量的所有引用都将引用局部变量,而不是封闭范围内的变量,直到局部变量的生存期结束。即使使用
-pedantic-Wall-Wextra

#include <iostream>

int main()
{
  int x = 42;
  {
      std::cout << x << '\n';
      int x = 21;
      std::cout << x << '\n';
  }
  std::cout << x << '\n';
}
我不知道lint或其他静态分析工具是否也会发现这样的问题。这是合法的,但不可取。

会检测到这一点。以下代码:

main (int argc, char *argv []) 
{
    char *x = 0;
    if (x)
    {
        char *x = 0;
    }
}
发出警告:

main.cpp  6  Warning 578: Declaration of symbol 'x' hides symbol 'x' (line 3)

GCC在这个AFAIR上做得更好…它们的范围不同。一个
x
是功能范围,一个是块范围。我认为这不容易引起警告。很多时候,它是人们想要的东西(例如,正式参数名和类成员-通常你不想发明新名称)@Ghita“通常你不想发明新名称”为什么不?@LuchianGrigore Yeas,在这种情况下很糟糕。但对于“属性”,我更喜欢懒惰..弱规则。很多人都是这样写的。“会有很多误报。@AndreyCpp仍然不是一个好主意。这条规则成为MISRA的一部分是有原因的。同样,这是我使用过的所有静态分析工具的例行检查。看看这个链接:是时候再次挖掘我的PC Lint副本了。我过去经常使用它,但现在已经改掉了这个习惯,@AndreyCpp-不确定你是否反对使用PC Lint。如果您通常这样编写代码,则不会出现误报问题,因为PC Lint具有完全的可配置性,可以关闭您希望的任何错误。Yikes,您的原始答案实际上是正确的,我的示例中的问题是无意的,但无论如何感谢您编辑的答案。我将保留我的问题,因为你的答案在这方面很有用。
main (int argc, char *argv []) 
{
    char *x = 0;
    if (x)
    {
        char *x = 0;
    }
}
main.cpp  6  Warning 578: Declaration of symbol 'x' hides symbol 'x' (line 3)