在有条件编译的使用时隐藏有关未使用的变量/函数的警告

时间:2017-04-05 07:54:46

标签: c++ macros compiler-warnings suppress-warnings

因此,在doctest(我的测试框架)中,用户可以通过定义生成以下代码和宏的DOCTEST_CONFIG_DISABLE标识符来禁用所有测试:

TEST_CASE("name") {
    int a = 5;
    int b = 6;
    CHECK(a == b);
}

在预处理器之后变成以下内容:

template<typename T>
void some_anon_func_123() {
    int a = 5;
    int b = 6;
}

这意味着将自注册测试用例转换为未实例化的模板函数,并将CHECK()宏(用作检查条件的if语句)转换为no-op - 如下所示:

#define CHECK(x) ((void)0) // if disabled

但是,如果用户在这样的单独函数中考虑了这样的测试代码:

static int g() {
    std::cout << "called!" << std::endl;
    return 42;
}

static void f() {
    int a = 5;
    CHECK(a == g());
}

TEST_CASE("name") {
    f();
}

然后会有未使用的函数和未使用的变量的警告。 doctest因制作0 warnings even on the most aggressive levels而感到自豪,所以这是不可接受的。

我尝试使用((void) ...)技巧传递宏参数,如下所示:

#define CHECK(x) ((void)(x))

这确实使警告(至少为ag())沉默,但仍然为该语句生成代码 - 如果我从{{1}调用f()函数我将在控制台中看到main()字符串。这是不可取的,因为我希望在构建中禁用测试用例和断言时(通过使用DOCTEST_CONFIG_DISABLE标识符)尽可能快地进行编译。如果用户有100 000个断言并且使用它们构建禁用,则他不会想要所有不必要的codegen并编译应该被禁用的宏的时间开销(called!)。

CHECK()必须在声明变量时使用 - 我不能将它粘贴在__attribute__((unused))宏中(或者我可以吗?我不知道......)。

不确定CHECK()是否有帮助 - 即使可能 - 它已知与GCC有关:

我的问题是否有解决方案 - 比如可能将表达式传递给某个模板或其他什么......? (需要C ++ 98解决方案)

我只是因为我经常被指控XY problem而解释我的问题...

修改

C ++ 11解决方案也可以 - 一些C ++ 11功能已开始有条件地进入库中......

1 个答案:

答案 0 :(得分:1)

所以,你想&#34;谎言&#34;编译器,你正在使用你实际上没有调用的函数。那么如何在不执行代码的情况下使用一段代码呢?

似乎唯一适用于所有流行编译器的东西是一个仅限C ++ 11的解决方案 - 一个永远不会被调用的lambda:

#define CHECK(x) [&](){ ((void)(x)); }

如果您绝对需要c ++ 98解决方案,sizeof也适用于许多编译器,MSVC是一个值得注意的例外:

#define CHECK(x) sizeof(x)

MSVC仍然会在表达式x中警告未调用的函数。

我想最大的覆盖范围,你可以使用两者的组合。