【发布时间】:2012-09-02 07:35:01
【问题描述】:
在使用未设置的局部变量或在初始化之前直接访问类或结构的成员时,捕获一些非常明显的错误非常好。在 Visual Studio 2008 中,您会在编译时收到“使用未初始化的局部变量”警告,并在调试时访问时遇到运行时检查失败。
但是,如果您通过其中一个函数访问未初始化结构的成员变量,您不会收到任何警告或断言。显然,最简单的解决方案是不要那样做,但没有人是完美的。
例如:
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
这让我感到惊讶,但它有一定的意义——编译器不能假设在未使用的结构上调用函数是错误的,否则你将如何初始化或构造它?任何更高级的东西都会很快带来许多其他复杂性,以至于它不会费心分类哪些函数可以调用以及何时调用,尤其是作为调试帮助。我知道我可以在类本身中设置自己的断言或错误检查,但这会使一些更简单的结构复杂化。
不过,在函数调用的上下文中,它难道不知道GetMember() 内部member 还没有初始化吗?我假设它不仅依赖于静态编译时推导,考虑到它在执行期间引发的Run-Time Check Failure #3,所以根据我目前对它的理解,应用相同的检查似乎是合理的。这只是这个特定编译器/调试器 (Visual Studio 2008) 的限制,还是更多地与 C++ 的工作方式有关?
【问题讨论】:
-
Is this just a limitation of this specific compiler/debugger (Visual Studio 2008), or more tied to how C++ works?标准不禁止使用未初始化的变量。这是 MSVC 调试功能。 -
@ForEveR 你不能使用未初始化的变量作为右值。
-
@LuchianGrigore “不能”是什么意思?程序格式正确,但它是UB,对。但这并不意味着“你不能”。
-
@ForEveR 是真的。但是您必须同意该评论弊大于利。我的意思是,说它没问题,只是因为它是一个格式良好的程序,但忽略了它是 UB(更糟糕的是,因为不需要诊断)......
-
@ForEveR 我知道你的意思,我只是说措辞可以更好。说它不被禁止有点暗示它没关系。至少对我来说。
标签: c++ visual-studio debugging visual-studio-2008