【问题标题】:Determine Uninitialized Variable in VC++在 VC++ 中确定未初始化的变量
【发布时间】:2013-08-30 09:47:47
【问题描述】:

我有这段代码,

#include <iostream>

void foo(int *a)
{
    std::cout<<*a<<std::endl;
}

int main()
{
    int i;
    foo(&i);
}

很明显正在使用未初始化的变量。

我尝试过/RTCu 以及依赖error C4700,但是对于上面的代码,编译器并没有将其标记为错误。

我也尝试运行代码分析,它报告为代码片段没有问题。

那么在我们的源代码中确定未初始化变量的可靠方法是什么?

我知道valgrind 在这里做了出色的工作,但它不是我的选择,因为我有很多对 Windows API 和 MFC 的调用。

【问题讨论】:

  • 这对您来说是“明显的”,但对编译器却不是:您通过指针间接将变量传递给(非内联)函数(请注意,使函数内联并启用内联确实会触发gcc 警告)。现在,不是答案,而是为什么要首先定义未初始化的变量?避免问题的一种简单方法是在定义变量时始终对其进行初始化(这意味着在您可以初始化之前不要定义它)。
  • @gx_:我不是在定义未初始化的变量,而是在清理代码库中可能存在的问题。我也不同意It is "evident" to you but not to the compiler。为了证明我的观点,我必须在上面的代码库上运行 Valgrind 并确定它的响应。
  • 感谢您的回复(我曾怀疑“不是我的代码”,但精确它不需要任何成本)。但我坚持认为,这对于编译器来说显然是;如果是,它会警告它(使foo inline 和 then 它对编译器来说变得很明显)。 valgrind 也不是编译器也不是静态分析工具,而是 dynamic 检查器。
  • 指针有效,因此 /RTCu 结束。在这种情况下,您依赖 /RTC,值 -858993460 明显突出。
  • 您将项目警告级别设置为什么?在项目属性 -> 配置属性 -> C/C++ -> 常规 -> 警告级别下。尝试将其设置为 Level 4 或 All 并重新编译。在某些情况下,编译器会捕获正在使用的未初始化变量,但不是全部。

标签: c++ visual-c++ visual-studio-2012 code-analysis initialization


【解决方案1】:

编译器没有可靠的方法来确定所有未初始化变量的情况。 Valgrind(和其他类似的工具)不是编译器,而是动态分析工具,就像上面用户 gx 所说的那样。还有一些静态分析工具可以检测到许多使用单元化变量的情况。但通常编译器无法匹配那些专门的工具。

【讨论】:

    【解决方案2】:

    关于静态分析部分:从 VS2013 开始,如果您可以访问另一个静态分析工具,我不会过多依赖默认分析器来捕获(尽管使用 VS 来捕获其他人可能会错过的东西很好) .尽管这里可能不是这种情况,但请注意,静态分析器可能会忽略他们在许多地方看到的模式或已被其他开发人员覆盖的模式作为可接受的规范。不过,如果 Coverity 没有报告这种情况,我会感到惊讶(抱歉,没有安装 ATM 进行测试)。如果它确实忽略了它,一个解释可能是它被认为是一个可能的共享内存地址。

    【讨论】:

    • Coverity(至少在我的设置中)也没有发现这一点。显然,分析的功能深度非常有限。在其他未初始化变量的情况下,编译过程通常会捕获它,所以也许他们依赖它。有趣的案例,不会猜到。
    猜你喜欢
    • 1970-01-01
    • 2016-07-31
    • 1970-01-01
    • 2014-04-05
    • 1970-01-01
    • 1970-01-01
    • 2017-02-23
    • 2016-03-01
    • 2013-08-25
    相关资源
    最近更新 更多