在类或结构中使用未设置的成员变量

时间:2012-09-08 21:34:42

标签: c++ visual-studio debugging visual-studio-2008

当使用未设置的局部变量或在初始化它们之前直接访问类或结构的成员时,捕获一些非常明显的错误是非常好的。在visual studio 2008中,您会在编译时获得“未初始化的本地变量”警告,并在调试时在访问时获得运行时检查失败。

但是,如果通过其中一个函数访问未初始化的struct的成员变量,则不会收到任何警告或断言。显然最简单的解决方案是不要那样做,但没有人是完美的。

例如:

struct Test
{
    float GetMember() const { return member; }
    float member;
};
Test test;
float f1 = test.member;      // Raises warning, asserts in VS debugger at runtime
float f2 = test.GetMember(); // No problem, just keeps on going

这让我感到惊讶,但它有一定道理 - 编译器不能假设在未使用的struct上调用函数是一个错误,或者你如何初始化或构造它?任何更高级的东西都会很快发现其他许多复杂问题,因此它不会分类哪些函数可以调用以及何时调用,特别是作为调试帮助。我知道我可以在类本身内设置自己的断言或错误检查,但这会使一些更简单的结构变得复杂。

但是,似乎在函数调用的上下文中,它是否知道GetMember()内部member尚未初始化?我假设它不仅仅依赖于静态编译时推导,因为它在执行期间会引发Run-Time Check Failure #3,所以基于我目前对它的理解,同样的检查应用似乎是合理的。这仅仅是这个特定编译器/调试器(Visual Studio 2008)的限制,还是与C ++的工作方式有关?

1 个答案:

答案 0 :(得分:2)

您可能会注意到警告是关于test未初始化的。这就是为什么警告&运行时故障仅适用于行

float f1 = test.member;

这会导致未定义的行为,并且,至少在调试模式下,MSVS会进行一些检查并且能够崩溃(在发布中,错误可能会被隐藏,并且您最终会在{{ 1}})。

然而,下一行并不直接导致UB。不读取f1,也不读取任何数据成员(直接)。调用一个方法,编译器无法知道成员函数会在未初始化的对象上产生UB。该功能可以只是在屏幕上打印一些东西,而不是读取任何成员,这是可以的。那么,编译器可能理论上知道,因为它看到了代码,但它没有深入挖掘。静态代码分析器可能会提醒您解决问题。