因此,在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))
这确实使警告(至少为a
和g()
)沉默,但仍然为该语句生成代码 - 如果我从{{1}调用f()
函数我将在控制台中看到main()
字符串。这是不可取的,因为我希望在构建中禁用测试用例和断言时(通过使用DOCTEST_CONFIG_DISABLE标识符)尽可能快地进行编译。如果用户有100 000个断言并且使用它们构建禁用,则他不会想要所有不必要的codegen并编译应该被禁用的宏的时间开销(called!
)。
CHECK()
必须在声明变量时使用 - 我不能将它粘贴在__attribute__((unused))
宏中(或者我可以吗?我不知道......)。
不确定CHECK()
是否有帮助 - 即使可能 - 它已知与GCC有关:
我的问题是否有解决方案 - 比如可能将表达式传递给某个模板或其他什么......? (需要C ++ 98解决方案)
我只是因为我经常被指控XY problem而解释我的问题...
修改
C ++ 11解决方案也可以 - 一些C ++ 11功能已开始有条件地进入库中......
答案 0 :(得分:1)
所以,你想&#34;谎言&#34;编译器,你正在使用你实际上没有调用的函数。那么如何在不执行代码的情况下使用一段代码呢?
似乎唯一适用于所有流行编译器的东西是一个仅限C ++ 11的解决方案 - 一个永远不会被调用的lambda:
#define CHECK(x) [&](){ ((void)(x)); }
如果您绝对需要c ++ 98解决方案,sizeof
也适用于许多编译器,MSVC是一个值得注意的例外:
#define CHECK(x) sizeof(x)
MSVC仍然会在表达式x
中警告未调用的函数。
我想最大的覆盖范围,你可以使用两者的组合。