例如,我如何才能摆脱源文件中的"warning: unnamed struct/union that defines no instances
“,而不是通过编译器命令行选项。
我想定义一个C宏CONST_BUG_ON
,我用它在编译时检查一些常量值。
#define CONST_BUG_ON(e) struct {int a:!(e);}
它会给出警告warning: unnamed struct/union that defines no instances
,但在本例中这不是一个真正的问题。
谢谢汤姆·坦纳
#define CONST_BUG_ON_3(e, l) struct buggy##l {int a:!(e);}
#define CONST_BUG_ON_2(e, l) CONST_BUG_ON_3(e, l)
#define CONST_BUG_ON(e) CONST_BUG_ON_2(e, __LINE__)
这很好,但仍然有一些问题:如果文件a
的第6行包含CONST_BUG_ON(e),文件a
包含在文件b
中,而文件b
的第6行包含CONST_BUG_ON(e),那么gcc抱怨重定义错误。使用__LINE__
的__COUNTER__
实例可能会很完美,但我的旧编译器不支持__COUNTER__
。
谢谢Basile Starynkevitch
#define CONST_BUG_ON(e) do { \
int tab[__builtin_constant_p(e)?1:-1] = {0}; \
if (tab[0]) abort(); } while (0)
这是一个C语句,只能放在函数中,我真的很想在函数之外使用它。
发布于 2012-08-27 13:11:31
解决编译器抱怨的一种方法是,你有一个未命名的结构,没有定义任何实例,就是给它一个名字:
#define CONST_BUG_ON(e) struct ForDebuggingOnly {int a:!(e);}
进行表达式测试的另一种方法是,如果e
为真,则声明(但不定义)具有非法大小的数组:
#define CONST_BUG_ON(e) extern int ForDebuggingOnly[(e) ? -1 : 1]
发布于 2012-08-27 12:47:07
假设您最近使用的是一个GCC编译器,您可以使用__builtin_constant_p测试编译时常量,可能使用
#define CONST_BUG_ON(e) do { \
int tab[__builtin_constant_p(e)?1:-1] = {0}; \
if (tab[0]) abort(); } while (0)
对于你关于忽略一些警告的问题,也许GCC diagnostic pragmas可以帮助你。
如果您希望CONST_BUG_ON
仅在声明上下文中工作,您可以尝试
#define CONST_BUG_ON(e) CONST_BUG_AT(e,__LINE__)
#define CONST_BUG_AT(e,l) \
extern int tab_##l[__builtin_constant_p(e)?0:-1];
最后,您甚至可以使用MELT (一种扩展GCC的高级领域特定语言)定制您的GCC编译器(使用特定于您的编译指示),但这将花费您数天的工作时间。
发布于 2012-08-27 13:17:51
您可以使用宏魔术,通过传入行号来为自己提供一个惟一的ID
#define CONST_BUG_ON_3(e, l) struct buggy##l {int a:!(e);}
#define CONST_BUG_ON_2(e, l) CONST_BUG_ON_3(e, l)
#define CONST_BUG_ON(e) CONST_BUG_ON_2(e, __LINE__)
这是相当棘手的,但它确实在每次使用时都会给出一个唯一的名称(第二级间接可能是虚假的,但这是我在一些经得起时间考验的代码中所拥有的)。
https://stackoverflow.com/questions/12142208
复制