所以我正在编写一个库,必须使用-pedantic -ansi -std=c++98 -Werror
和-Weverything
为clang和-Wall -Wextra
为gcc构建,我有这个宏TESTSUITE(X)
的目的是在全球范围内使用,如下所示:
TESTSUITE(current testsuite);
它的作用是使用字符串调用函数(在程序启动时通过初始化虚拟var):
#define TESTSUITE(name) \
static int ANONYMOUS_VARIABLE(SOME_PREFIX) = setTestSuiteName(#name)
问题是,这会在-Wglobal-constructors
的clang下生成警告。
如果我用这样的_Pragma
包围它:
#define TESTSUITE(name) \
_Pragma("clang diagnostic push"); \
_Pragma("clang diagnostic ignored \"-Wglobal-constructors\""); \
static int ANONYMOUS_VARIABLE(SOME_PREFIX) = setTestSuiteName(#name) \
_Pragma("clang diagnostic pop")
编译后不需要使用宏后使用分号(当它丢失时-pedantic
会出错)。
如果我在宏的末尾添加它
static int ANONYMOUS_VARIABLE(SOME_PREFIX) = 5
分号将是必需的,但我会收到一个未使用的变量的警告,我无法保持沉默(因为如果我用_Pragma
语句包围它,我将返回到不需要分号的方块1。/ p>
那么有没有人知道我怎么能要求分号并且还有0个警告?
答案 0 :(得分:4)
您可以在宏的末尾添加一个函数声明:
#define TESTSUITE(name) \
//... \
void ANONYMOUS_FUNCTION()
函数名称甚至不必在不同的TESTSUITE
宏之间有所不同。如果它在其他任何地方都没有使用它就足够了,所以它不会参与任何超载。
答案 1 :(得分:3)
聚会晚了一点,但我想我会为以后寻找答案的人而欢呼。推荐的方法是将宏包装在do {....} while (0)
中。该操作仅执行一次,编译器通常会为您优化此操作,不生成任何额外的代码,但仍实现抽象。
来源:https://gcc.gnu.org/onlinedocs/cpp/Swallowing-the-Semicolon.html
答案 2 :(得分:2)
类似于@ thomas-eding的解决方案,您可以将static_assert(true, "")
放在宏的末尾以要求使用分号。
这在类和函数的内部和外部都起作用。
它不污染任何名称空间,也不生成任何代码。
答案 3 :(得分:0)
我在宏的末尾使用enum {}
来强制分号。
这在类和函数的内部和外部都起作用。
这种方法不会污染任何名称空间,也不会生成任何代码。