如何在宏后要求分号
How to require a semicolon after a macro
所以我正在编写一个库,必须使用 -pedantic -ansi -std=c++98 -Werror
和 -Weverything
为 clang 和 -Wall -Wextra
为 gcc 构建,我有这个宏 TESTSUITE(X)
像这样在全球范围内使用:
TESTSUITE(current testsuite);
它所做的是使用以下字符串调用函数(在程序启动时通过初始化虚拟变量):
#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)。
那么有没有人知道我如何要求分号并且还有 0 个警告?
您可以在宏的末尾添加一个函数声明:
#define TESTSUITE(name) \
//... \
void ANONYMOUS_FUNCTION()
函数名称甚至不必在不同的 TESTSUITE
宏中有所不同。如果它只是不在其他任何地方使用就足够了,所以它不参与任何重载。
我在宏的末尾使用 enum {}
来强制使用分号。
这在内部和外部都有效 类 和功能。
这种方法不会污染任何命名空间,也不会生成任何代码。
类似于@thomas-eding 的解决方案,您可以将 static_assert(true, "")
放在宏的末尾以要求分号。
这在内部和外部都有效 类 和功能。
并且不污染任何命名空间,不生成任何代码。
聚会有点晚了,但我想我会为稍后寻找答案的人插话。实现此目的的推荐方法是将宏包装在 do {....} while (0)
中。这只会执行一次,编译器通常会为您优化它,不会生成额外的代码,但仍会实现抽象。
来源:https://gcc.gnu.org/onlinedocs/cpp/Swallowing-the-Semicolon.html
所以我正在编写一个库,必须使用 -pedantic -ansi -std=c++98 -Werror
和 -Weverything
为 clang 和 -Wall -Wextra
为 gcc 构建,我有这个宏 TESTSUITE(X)
像这样在全球范围内使用:
TESTSUITE(current testsuite);
它所做的是使用以下字符串调用函数(在程序启动时通过初始化虚拟变量):
#define TESTSUITE(name) \
static int ANONYMOUS_VARIABLE(SOME_PREFIX) = setTestSuiteName(#name)
问题是这会在 -Wglobal-constructors
.
如果我像这样用 _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)。
那么有没有人知道我如何要求分号并且还有 0 个警告?
您可以在宏的末尾添加一个函数声明:
#define TESTSUITE(name) \
//... \
void ANONYMOUS_FUNCTION()
函数名称甚至不必在不同的 TESTSUITE
宏中有所不同。如果它只是不在其他任何地方使用就足够了,所以它不参与任何重载。
我在宏的末尾使用 enum {}
来强制使用分号。
这在内部和外部都有效 类 和功能。
这种方法不会污染任何命名空间,也不会生成任何代码。
类似于@thomas-eding 的解决方案,您可以将 static_assert(true, "")
放在宏的末尾以要求分号。
这在内部和外部都有效 类 和功能。
并且不污染任何命名空间,不生成任何代码。
聚会有点晚了,但我想我会为稍后寻找答案的人插话。实现此目的的推荐方法是将宏包装在 do {....} while (0)
中。这只会执行一次,编译器通常会为您优化它,不会生成额外的代码,但仍会实现抽象。
来源:https://gcc.gnu.org/onlinedocs/cpp/Swallowing-the-Semicolon.html