在条件编译使用时对未使用 variables/functions 的警告静音
silence warnings about unused variables/functions at the point of their conditionally compiled usage
因此在doctest (my testing framework) the user can disable all tests by defining the 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 prides itself with producing 0 warnings even on the most aggressive levels 所以这是不可接受的。
我尝试通过将宏参数传递给它来使用 ((void) ...)
技巧,如下所示:
#define CHECK(x) ((void)(x))
这确实消除了警告(至少 a
和 g()
)但是仍然为该语句生成代码 - 如果我从我的 [ 调用 f()
函数=21=] 我将在控制台中看到 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 功能已经开始有条件地潜入库中......
因此,您想 "lie" 向编译器表明您正在使用您实际上并未调用的函数。那么如何在不执行的情况下使用一段代码呢?
似乎唯一适用于所有流行编译器的是仅适用于 C++11 的解决方案 - 一个从未被调用的 lambda:
#define CHECK(x) [&](){ ((void)(x)); }
如果您绝对需要 c++98 解决方案,sizeof
也适用于许多编译器,MSVC 是一个明显的例外:
#define CHECK(x) sizeof(x)
MSVC 仍会针对表达式 x
.
中未调用的函数发出警告
我想为了获得最大覆盖率,您可以结合使用两者。
因此在doctest (my testing framework) the user can disable all tests by defining the 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 prides itself with producing 0 warnings even on the most aggressive levels 所以这是不可接受的。
我尝试通过将宏参数传递给它来使用 ((void) ...)
技巧,如下所示:
#define CHECK(x) ((void)(x))
这确实消除了警告(至少 a
和 g()
)但是仍然为该语句生成代码 - 如果我从我的 [ 调用 f()
函数=21=] 我将在控制台中看到 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 功能已经开始有条件地潜入库中......
因此,您想 "lie" 向编译器表明您正在使用您实际上并未调用的函数。那么如何在不执行的情况下使用一段代码呢?
似乎唯一适用于所有流行编译器的是仅适用于 C++11 的解决方案 - 一个从未被调用的 lambda:
#define CHECK(x) [&](){ ((void)(x)); }
如果您绝对需要 c++98 解决方案,sizeof
也适用于许多编译器,MSVC 是一个明显的例外:
#define CHECK(x) sizeof(x)
MSVC 仍会针对表达式 x
.
我想为了获得最大覆盖率,您可以结合使用两者。