所以在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 语句)变成了空操作 - 比如这个:
#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而自豪所以这是 Not Acceptable 。
我尝试通过将宏参数传递给它来使用 ((void) ...)
技巧:
#define CHECK(x) ((void)(x))
这确实消除了警告(至少对于 a
和 g()
)但是仍然为该语句生成代码 - 如果我调用 我的
函数 我将看到 main()
中的 f()called!
字符串打印在控制台中。这是不可取的,因为我希望在从构建中禁用测试用例和断言时编译尽可能快(通过使用 DOCTEST_CONFIG_DISABLE 标识符)。如果用户有 100 000 个断言并在禁用它们的情况下构建,他不希望所有不必要的代码生成和编译时间开销用于应该被禁用的宏(CHECK()
一个)。
__attribute__((unused))
必须在声明变量时使用 - 我不能将它粘贴在 CHECK()
宏中(或者我可以?我不知道...)。
不确定 _Pragma()
是否有帮助——即使有帮助——已知 GCC 存在问题:
- https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55578
- https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69543
我的问题是否有解决方案 - 比如将表达式传递给某个模板或其他...? (需要 C++98 解决方案)
我非常详细地解释了我的问题,只是因为我经常被指责为 XY problem ...
编辑:
C++11 解决方案也可以 - 一些 C++11 特性已经开始有条件地潜入库中......
最佳答案
因此,您想向编译器“撒谎”,说您正在使用您实际上并未调用的函数。那么如何在不执行的情况下使用一段代码呢?
似乎唯一适用于所有流行编译器的是仅适用于 C++11 的解决方案——一个从未被调用的 lambda:
#define CHECK(x) [&](){ ((void)(x)); }
如果您绝对需要 c++98 解决方案,sizeof
也适用于许多编译器,MSVC 是一个明显的异常(exception):
#define CHECK(x) sizeof(x)
对于表达式 x
中未调用的函数,MSVC 仍会发出警告。
我想为了获得最大覆盖率,您可以结合使用两者。
关于c++ - 在条件编译使用时对未使用的变量/函数发出静音警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43225154/