这会导致未定义的行为吗?

时间:2009-05-16 17:24:48

标签: c++ undefined

我在复制和查找错误原因方面遇到了很大的问题。出现似乎是完全随机的,所以我怀疑某处有一个未初始化的变量。但后来我找到了这段代码:

CMyClass obj; // A
obj.DoStuff();

if ( somebool )
{
    CMyClass obj; // B
    obj.DoStuff();
}

obj.DoOtherStuff();

似乎DoOtherStuff()要么在“B”上完成,要么B.DoStuff()有时实际上在A上工作 - 即实际上在第一个obj上调用了DoStuff()。

这会发生吗?我不认为我收到了编译器警告(我现在修改了代码,希望它可能有所帮助)。似乎非常可能这段实际代码是我想要找到的bug的地方,但当然还有其他原因我还没有发现。

6 个答案:

答案 0 :(得分:5)

编写的代码应该有效。第一次拨打DoStuff()和最后一次拨打DoOtherStuff()只能发送到A

DoStuff()块中对if(somebool) { }的调用只能发送到B

来自standard

  

3.3.2本地范围

     
      
  1. 块(6.3)中声明的名称是该块的本地名称。它的潜在范围始于其声明(3.3.1)和   结束于其声明区域的末尾。
  2.   

  

3.3.7名称隐藏

     
      
  1. 可以通过嵌套声明性区域或派生类(10.2)中相同名称的显式声明来隐藏名称。
  2.   

话虽如此,也许这不是该代码的作者的意图。如果变量具有相同的名称,则意图可能只有该变量的一个实例,并且在循环内创建的B实例是错误的。你是否经历过逻辑,看看第二个实例是否有意义?

答案 1 :(得分:3)

除非obj.DoStuff()对某个全局对象进行更改,否则Valentin指出它应该全部包含在if语句的范围内

答案 2 :(得分:2)

与全局变量同名的局部变量会隐藏该块内的全局变量。但是,全局范围运算符(::)可用于告诉编译器您的全局版本

CMyClass obj; // A
obj.DoStuff();
if ( somebool )
{ 
 CMyClass obj; // B  
 obj.DoStuff();  //does on B
 ::obj.DoStuff(); //does on A
}
obj.DoOtherStuff(); //this will call A because B is destroyed

因此当局部变量B超出范围时会被销毁。拥有与全局变量同名的局部变量通常是一个麻烦的召唤,所以尽量避免使用。

答案 3 :(得分:2)

如果您使用GCC,您可以(并且 - 在我看来 - 应该)使用-Wshadow,它会在例如您的示例中的情况下发出警告,这通常会带来非常微妙的错误。

然而,就像许多其他人已经说过的那样,你粘贴的代码是正确的,做你期望的,并且不是未定义的行为。

答案 4 :(得分:1)

不,这不可能发生。

编译器保证在退出if作用域时正确销毁B对象,而在alive时它会作用于自己的地址空间。

错误发生在其他地方。

答案 5 :(得分:0)

您的代码可能在语法上是正确的,但这些方法有何用处?例如,堆栈溢出可能会导致您正在观察的怪异行为。