如何在C源代码中关闭指定的警告?

时间:2012-08-27 12:42:57

标签: c gcc compile-time

例如,如何在源文件中删除“warning: unnamed struct/union that defines no instances”,而不是通过编译器命令行选项。

我想定义一个C宏CONST_BUG_ON,我用它在编译时检查一些const值。

#define CONST_BUG_ON(e)        struct  {int a:!(e);}

它会发出警告warning: unnamed struct/union that defines no instances,但在这种情况下,这不是一个真正的问题。

感谢Tom Tanner

#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和第6行文件b aslo包含CONST_BUG_ON(e),然后gcc抱怨重新定义错误。使用__COUNTER__ __LINE__的instade可能很完美,但我的旧编译器不支持__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语句,只能放在一个函数中,我真的很想在函数外面使用它。

4 个答案:

答案 0 :(得分:3)

解决编译器抱怨的一种方法是你有一个未命名的结构,定义没有实例是给它一个名字:

#define CONST_BUG_ON(e)        struct ForDebuggingOnly {int a:!(e);}

获取所需表达式测试的另一种方法是声明(但不定义)如果e为真,则具有非法大小的数组:

#define CONST_BUG_ON(e)    extern int ForDebuggingOnly[(e) ? -1 : 1]

答案 1 :(得分:1)

假设最近的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编译器(使用你的特定编译指示),但这需要你几天的工作。

答案 2 :(得分:1)

您可以使用宏魔术通过传入行号

为自己提供唯一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__)

这是相当icky但它​​确实每次使用时都会给出一个唯一的名称(第二级间接可能是虚假的,但这是我在一些经得起时间考验的代码中所拥有的。)

答案 3 :(得分:1)

您尝试的操作看起来像是编译时断言编译时断言宏。有多种方法可以做到这一点,通常涉及断言失败时具有负维度的数组。许多项目都会调用此宏CT_ASSERT(),并且a bunch of Stackoverflow questions与它们相关。