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