在C中的宏中声明变量,允许尾随分号
对于宏声明来说,这是一个愚蠢的问题,但我已经遇到过好几次了,我很好奇是否有我遗漏的解决方案 我有一个声明变量的宏,我想确保这些变量没有被错误初始化在C中的宏中声明变量,允许尾随分号,c,macros,C,Macros,对于宏声明来说,这是一个愚蠢的问题,但我已经遇到过好几次了,我很好奇是否有我遗漏的解决方案 我有一个声明变量的宏,我想确保这些变量没有被错误初始化 #define DECLARE_FOO(var) \ int _##var##_a = 0; \ int _##var##_b = 0 示例用法: DECLARE_FOO(var); 然而这允许 DECLARE_FOO(var) + 1; 我可以暂时忽略这一点,但我不允许这样做。简单的 #define DECLARE_FOO(v
#define DECLARE_FOO(var) \
int _##var##_a = 0; \
int _##var##_b = 0
示例用法:
DECLARE_FOO(var);
然而这允许
DECLARE_FOO(var) + 1;
我可以暂时忽略这一点,但我不允许这样做。简单的
#define DECLARE_FOO(var) \
int _##var##_a = 0; \
int _##var##_b = 0;
但是,现在我必须从声明中删除分号,否则我将收到此警告
DECLARE_FOO(var);
int bar;
ISO C90禁止混合声明和代码[-Werror=声明后声明]
所以,我必须这样做
DECLARE_FOO(var)
int bar;
…它正确展开,但对于阅读代码而不检查宏定义的人来说,它看起来很奇怪。另外,不展开宏的编辑器可能会因为语法不正确而发出警告
是否有某种方法可以禁止对变量赋值,但也可以使用分号结束声明的使用
使现代化
我的问题不是很清楚,但是-Werror=语句后声明推断C90是这里的一个要求,在这种情况下,混合语句的答案不起作用,因为可能会有继续声明。在宏中添加一个无操作表达式:
#define DECLARE_FOO(var) \
int _##var##_a = 0; \
int _##var##_b = 0; \
(void) 0
顺便说一句:如果使用宏时没有分号,这甚至会失败
更新:另一个技巧:使宏的最后一行成为一个外部声明,它也是一个no-op,但是没有分号会阻塞
#define DECLARE_FOO(var) \
int _##var##_a = 0; \
int _##var##_b = 0; \
extern int _##var##_ext
将无操作表达式添加到宏:
#define DECLARE_FOO(var) \
int _##var##_a = 0; \
int _##var##_b = 0; \
(void) 0
顺便说一句:如果使用宏时没有分号,这甚至会失败
更新:另一个技巧:使宏的最后一行成为一个外部声明,它也是一个no-op,但是没有分号会阻塞
#define DECLARE_FOO(var) \
int _##var##_a = 0; \
int _##var##_b = 0; \
extern int _##var##_ext
只要C90不允许混合减速和语句,就不可能防止宏后面出现拖尾文本 但是,可以使用三元运算符忽略尾随文本,这是一个相当糟糕的解决方案,我不建议使用它
#define DECLARE_FOO(var) \
int _##var##_a = 0; \
int _##var##_b = 1 ? 0 : 0
这不会引发错误,但+1将被忽略
DECLARE_FOO(var) + 1;
只要C90不允许混合减速和语句,就不可能防止宏后面出现拖尾文本 但是,可以使用三元运算符忽略尾随文本,这是一个相当糟糕的解决方案,我不建议使用它
#define DECLARE_FOO(var) \
int _##var##_a = 0; \
int _##var##_b = 1 ? 0 : 0
这不会引发错误,但+1将被忽略
DECLARE_FOO(var) + 1;
为什么你还在按照C90标准编程?自1999年以来,我们可以在C语言中混合使用代码和声明。因此,只要切换到更现代的方言,编译器就会忽略双分号。@cmaster,因为它与MSVC2008兼容,仍然禁止混合声明和代码。尽管我在Linux上使用GCC4.8和Clang,但为什么您仍在使用C90标准编程?自1999年以来,我们可以在C语言中混合使用代码和声明。因此,只要切换到更现代的方言,编译器就会忽略双分号。@cmaster,因为它与MSVC2008兼容,仍然禁止混合声明和代码。尽管我在LinuxIt上使用GCC4.8和Clang,这会给出警告/错误,但ISO C90禁止混合声明和代码,前提是您连续两次调用macto。c99确实允许混合代码和声明。不只是在一行中调用两次,而是在它之后定义任何变量,这使得它非常有限。是的,我知道。关于外部使用的发现很好!,虽然后来在名称空间中出现了一个虚拟变量,但我现在从GCC得到一个警告,它未使用,这可能仍然是迄今为止最接近答案的一个。这给出了警告/错误,ISO C90禁止混合声明和代码,仅当您连续两次调用macto时。c99确实允许混合代码和声明。不只是在一行中调用两次,而是在它之后定义任何变量,这使得它非常有限。是的,我知道。关于外部使用的发现很好!,虽然最后在名称空间中出现了一个虚拟变量,我现在从GCC得到一个警告,它未被使用,但它可能仍然是迄今为止最接近答案的东西。