zoukankan      html  css  js  c++  java
  • Visual Studio /analyze不好之处---漏报(三)

    分析是一种强大的VisualC++特性,可以帮助发现bug。然而,它有时会在不存在问题的情况下发现问题。不幸的是,这些误报,就像这里报道的那样,使/分析变得不那么有用,因为严重的错误最终会被“狼”的叫声淹没。在这篇文章中,我描述了另一个令人沮丧的误报,它展示了一个编译器完全无法理解别名的例子。

    VisualStudio2012中的/analyze不再对这些构造发出警告。但不幸的是,它们已经从假阳性变成了假阴性。在GetInt()示例中,如果注释掉了部分初始化,则不会出现警告,即使返回的是部分未初始化的对象。更好吗?我不确定。

    这些测试都是用Visual Studio 2010 SP1,C/C++优化编译器版本16.00 .40219.01为80×86。

    未初始化的数据

    我们有一些代码可以从文件或网络流中读取并初始化各种变量。当我们需要初始化一个整数时,我们调用这个函数:

    int GetInt(const char* p)
    {
        int result;
        char* pDest = (char*)&result;
        pDest[0] = p[0];
        pDest[1] = p[1];
        pDest[2] = p[2];
        pDest[3] = p[3];
        return result; // warning C6001: Using uninitialized memory ‘result’
    }

    编译器无法或不愿意告诉我们已经写入了结果的所有四个字节,因此在返回结果时会发出警告。
    有人可能会说编译器在技术上是正确的。关于C++中的混叠的规则有点深奥,所以我相信这是合法的,但我不能肯定。使用联合是一种通知编译器正在发生别名的方法,因此我尝试:

        union intAlias
        {
            int i;
            char c[4];
        };
    
        int GetIntFixAttempt(const char* p)
        {
            intAlias result;
            char* pDest = result.c;
            pDest[0] = p[0];
            pDest[1] = p[1];
            pDest[2] = p[2];
            pDest[3] = p[3];
            return result.i; // warning C6001: Using uninitialized memory ‘result’
        }

    没有骰子。但是我走的是正确的道路。接下来,我尝试像这样重写代码,使编译器更容易跟踪:

        union intAlias
        {
            int i;
            char c[4];
        };
    
        int GetIntFixed(const char* p)
        {
            intAlias result;
            result.c[0] = p[0];
            result.c[1] = p[1];
            result.c[2] = p[2];
            result.c[3] = p[3];
            return result.i; // No warning!
        }

    终于成功了!很高兴知道,我可以找到代码,让/analyze意识到我没有使用未初始化的内存,但我不想经历这样的体操。所有关于代码将如何执行的信息都是可用的,所以没有理论上的原因说明编译器不能正确地推理,但是它失败了。
    如果编译器想给我一个关于错误别名的警告,那么我可以尊重它,但是它当前的警告是错误的,这使得/analyze更难使用。

  • 相关阅读:
    学习之路 1-2
    学习之路 1-1
    【LifecycleException】: org.apache.catalina.LifecycleException: A child container failed during start 解决
    【JAVA】java中int转成String位数不足前面补零例如:1->001
    【Docker】 Error running deviceCreate (CreateSnapDeviceRaw)
    【java】解决java compiler level does not match the version of the installed java project facet
    【Mysql】SpringBoot阿里Druid数据源连接池配置
    【JVM】JVM优化过程全记录
    【JavaScript】windows.open用法详解
    【Java】JavaMail 554错误解决方法
  • 原文地址:https://www.cnblogs.com/yilang/p/13376176.html
Copyright © 2011-2022 走看看