如何让X宏与do while 0兼容?checkpatch.pl报错且逻辑异常
解决X宏与do-while(0)的冲突问题
我来帮你捋清楚这个问题:你之所以遇到冲突,是因为do-while(0)的适用场景不对——它是用来封装那些作为独立语句调用的宏,避免悬空else或语法歧义,但你的X_TYPES是用来生成枚举、数组的列表项,本质是数据声明的一部分,不是可执行语句,直接套do-while(0)肯定会把结构搞坏。
正确的写法(完全不需要do-while(0))
checkpatch.pl的提示应该是针对多行宏的格式规范,并不是要求所有宏都套do-while(0)。你可以把X_TYPES改成纯粹的X宏调用序列,用反斜杠正确换行就行,这样既符合checkpatch的要求,又能保留原有逻辑:
#define X_TYPES \ X(BABA, "baba") \ X(INVALID, "invalid") #define X(type, name) type, enum x_type { X_TYPES }; #undef X #define X(type, name) name, const char *x_name[] = { X_TYPES }; #undef X int main() { return 0; }
这样展开后:
- 枚举会变成
enum x_type { BABA, INVALID };,完全合法 - 字符串数组会变成
const char *x_name[] = { "baba", "invalid" };,也没问题
如果checkpatch还挑刺的话
要是checkpatch.pl还是对X_TYPES的定义有异议,大概率是它误判了这个宏的用途。你可以在宏定义上方加个注释说明,告诉检查工具这个宏是用来生成列表的,不需要do-while:
/* List-generating X macro, no do-while needed */ #define X_TYPES \ X(BABA, "baba") \ X(INVALID, "invalid")
一般代码检查工具会识别这类注释,不再报错。
再啰嗦两句为什么do-while(0)在这里不行
do-while(0)的核心作用是让宏在作为语句调用时,不管有没有加分号都能正常编译,比如:
#define DO_SOMETHING() do { printf("hi"); } while(0) // 调用时加不加;都没问题 DO_SOMETHING(); DO_SOMETHING()
但你的X_TYPES是要放到enum { ... }或者char*[] = { ... }里的,这些位置只能放逗号分隔的标识符/字符串,不能放语句块,所以套do-while(0)就会直接报语法错误,完全是用错地方了。
内容的提问来源于stack exchange,提问作者user3053970
相关产品推荐
相关产品推荐

