【问题标题】:I want tell the VC++ Compiler to compile all code. Can it be done?我想告诉 VC++ 编译器编译所有代码。可以做到吗?
【发布时间】:2008-09-19 19:48:18
【问题描述】:

我将 VS2005 VC++ 用于非托管 C++。我有 VSTS 并且正在尝试使用代码覆盖率工具来完成关于单元测试的两件事:

  1. 查看我在测试中引用的代码有多少正在执行
  2. 查看我的测试代码中有多少方法(如果有)根本没有经过单元测试

设置 VSTS 代码覆盖率工具(请参阅 link text)并完成任务 #1 非常简单。然而#2对我来说是一个令人惊讶的挑战。这是我的测试代码。

class CodeCoverageTarget
{
public:
    std::string ThisMethodRuns() {
         return "Running";
    }

    std::string ThisMethodDoesNotRun() {
        return "Not Running";
    }
};



#include <iostream>
#include "CodeCoverageTarget.h"
using namespace std;
int main()

{
    CodeCoverageTarget cct; 
    cout<<cct.ThisMethodRuns()<<endl;
}

当上述两个方法都在类中定义时,编译器会自动从 obj 文件中删除 ThisMethodDoesNotRun()。如果我将它的定义移到类之外,那么它会包含在 obj 文件中,并且代码覆盖率工具显示它根本没有被执行过。在大多数情况下,我希望编译器为我执行此消除,但对于代码覆盖工具,它会破坏大部分价值(例如,查找未经测试的方法)。我已经尝试了很多方法来告诉编译器停止对我聪明并编译所有内容,但我很难过。如果代码覆盖工具能弥补这一点会很好(我想通过扫描源代码并将其与链接器输出匹配),但我没有发现任何迹象表明它有一个特殊的模式可以打开。我在这里完全遗漏了一些简单的东西,还是用 VC++ 编译器 + VSTS 代码覆盖工具不可能做到这一点?

提前致谢, 克格勃

【问题讨论】:

标签: c++ compiler-construction visual-studio-2005 code-coverage


【解决方案1】:

您可以尝试添加一行代码以仅在某些条件为真时调用该函数,并保证该条件永远不会为真。只要确保编译器无法解决这个问题。例如,


int main(int argc, char **argv)
{
  if(argv == NULL)  // C runtime says this won't happen
    someMethodWhichIsntReallyEverCalled();
}

【讨论】:

  • 我在这里要解决的问题是检测已经编写并在单元测试中完全忘记的功能/方法。这应该可以,但如果我记得这样做,我可能会记得对函数进行单元测试。谢谢!凯文
【解决方案2】:

确保您的函数不被丢弃的一种方法是导出它们。您可以通过在函数声明中添加__declspec(dllexport) 来做到这一点。最好将其包装在 C 预处理器宏中,以便您可以将其关闭,因为它是特定于编译器的,您可能不希望所有构建都导出符号。另一种导出函数的方法是创建一个.DEF file

如果内联是问题所在,您也可以使用__declspec(noinline) 获得成功。

您的代码是否在静态库中,然后编译成测试 EXE/DLL?链接器将自动丢弃静态库中未引用的目标文件。示例:如果静态库包含 a.objb.obj 以及您将其链接到来自 b.obj 而不是 a.obj 的引用符号的 EXE/DLL,则 a.obj 的内容将不会链接到可执行文件或 DLL。但是,在重新阅读您的描述后,这听起来不像是这里发生的事情。

【讨论】:

    【解决方案3】:

    抱歉,我应该澄清一下,我正在使用内联和所有优化来构建调试模式。此外,代码甚至在发生内联之前就被删除了,因为它从来没有被考虑过内联。

    【讨论】:

      【解决方案4】:

      关闭函数的内联。最简单的方法就是在调试模式下编译。

      编辑:看到您的说明后,我发现我的回答有误。也许如果您使用“inline”关键字将函数的主体移动到 .h 文件的另一部分?

      【讨论】:

        【解决方案5】:

        另一个选项是根据您的构建在内联和非内联函数之间切换,使用 .inl 文件,如下所示:

        在 foo.inl 文件中:

        inline std::string Foo::ThisMethodDoesNotRun()
        {
            return "Not Running";
        }
        

        在 foo.h 中:

        #if !COVERAGE_BUILD
        #include "foo.inl"
        #endif
        

        在 foo.cpp 中:

        #if COVERAGE_BUILD
        #define inline
        #include "foo.inl"
        #endif
        

        【讨论】:

        • 谢谢唐,我们有很多遗留代码,所以尝试改造将是一个问题。凯文
        猜你喜欢
        • 1970-01-01
        • 2014-01-16
        • 2010-09-09
        • 1970-01-01
        • 2012-04-28
        • 1970-01-01
        • 2023-03-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多