背景
注意:这对于问题来说并不重要
我有一些宏,它们充当属性的更通用版本,我将它们附加到函数中。根据编译器和编译器版本,它们将扩展为属性(例如__attribute__((nonnull))
),或警告(例如_Pragma("message \"nonnull attribute unavailable\"")
)。由于属性宏可以按任何顺序排列,这可能导致它们混杂在一起(例如警告属性属性警告警告)。
结果是我可以得到如下代码:
样本
#pragma message "one"
__attribute__((cold))
#pragma message "two"
__attribute__((noreturn))
#pragma message "three"
void test(void);
问题
运行后clang
,此示例代码编译完美,并按预期打印三条消息。
input.c:1:9: warning: one [-W#pragma-messages]
#pragma message "one"
^
input.c:3:9: warning: two [-W#pragma-messages]
#pragma message "two"
^
input.c:5:9: warning: three [-W#pragma-messages]
#pragma message "three"
^
但是运行时gcc
,第二个出现错误#pragma
。如果我将其注释掉,第三个又会出现错误#pragma
。
input.c:1:9: note: ‘#pragma message: one’
1 | #pragma message "one"
| ^~~~~~~
input.c:3:9: error: expected identifier or ‘(’ before ‘#pragma’
3 | #pragma message "two"
| ^~~~~~~
input.c:1:9: note: ‘#pragma message: one’
1 | #pragma message "one"
| ^~~~~~~
input.c:5:9: error: expected identifier or ‘(’ before ‘#pragma’
5 | #pragma message "three"
| ^~~~~~~
经过实验,似乎在 之后gcc
不接受任何指令。#pragma
__attribute__
可重现的示例
取消注释#pragma
会导致 GCC v11.4.0 上出现可重现的错误
__attribute__((nonnull))
// #pragma message "this is an error"
void test(void);
问题
是否有任何修复或解决方案允许我将#pragma
和__attribute__
指令混合在一起gcc
,就像clang
允许一样?