【问题标题】:How to close specified warning in C source code?如何关闭 C 源代码中的指定警告?
【发布时间】:2012-08-27 12:42:57
【问题描述】:

例如,我怎样才能摆脱源文件中的“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,但在这种情况下它不是一个真正的问题。

感谢汤姆·坦纳

#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 抱怨重新定义错误。使用__COUNTER__ 替代__LINE__ 可能会完美,但我的旧编译器不支持__COUNTER__

感谢巴西尔·斯塔林克维奇

#define CONST_BUG_ON(e) do { \
   int tab[__builtin_constant_p(e)?1:-1] = {0}; \
   if (tab[0]) abort(); } while (0)

这是一个C语句,只能放在函数中,我很想在函数外使用。

【问题讨论】:

  • 发帖人的问题中有一个 GCC 标签
  • 为什么这对您如此重要?真正的用例是什么??

标签: c gcc compile-time


【解决方案1】:

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

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

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

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

【讨论】:

  • 如果多次使用 CONST_BUG_ON,这段代码不起作用,gcc报redefine error。
  • @yangwen:使用我展示的第二种方法,extern int
【解决方案2】:

您可以使用宏魔法通过传入行号来给自己一个唯一的 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__)

这很恶心,但每次使用时都会给出一个唯一的名称(第二级间接可能是虚假的,但这是我在一些经受住时间考验的代码中所拥有的)。

【讨论】:

  • 很好,但还是有一些问题:如果文件“a”的第6行包含CONST_BUG_ON(e),并且文件“a”被文件“b”包含,并且文件“的第6行” b" aslo 包含CONST_BUG_ON(e),然后 gcc 抱怨重新定义错误。使用 LINE__COUNTER__ instade 可能完美,但我的旧编译器不支持__COUNTER__
  • 我认为如果你有这样的源代码设置,你可能会遇到其他问题。
【解决方案3】:

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

【讨论】:

    【解决方案4】:

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

    【讨论】:

      猜你喜欢
      • 2010-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-21
      • 2013-03-27
      • 2010-10-28
      • 1970-01-01
      相关资源
      最近更新 更多