代码之家  ›  专栏  ›  技术社区  ›  Emanuele Paolini

函数外没有op语句

  •  1
  • Emanuele Paolini  · 技术社区  · 6 年前

    我的代码包含许多行,例如:

    static_assert(sizeof(my_stuct)==42, "check struct size");
    

    我想在没有实现静态断言的编译器上编译。所以我想让这些台词成为禁止语。我试过:

    #define static_assert(COND, MSG) 
    

    它工作正常,但我得到一个警告与叮当声编译器:

    warning: extra ';' outside of a function [-Wextra-semi]
    

    有没有一个简单的no op C语句可以在以分号结尾的函数外使用,并且可以重复使用?

    4 回复  |  直到 6 年前
        1
  •  3
  •   DevSolar    6 年前

    我想在没有实现静态断言的编译器上编译。所以我想让这些台词变成禁止。

    为什么不合并Lundin的答案(检查当前编译器 它是否实现)与一个 实施 属于 static_assert

    从复制实现 PDCLib (这是 CC0 许可证):

    /* with dodgy implementations, you could also #ifndef static_assert */
    #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112
    #define _PDCLIB_cc( x, y )     x ## y
    #define _PDCLIB_concat( x, y ) _PDCLIB_cc( x, y )
    
    #define static_assert( e, m ) enum { _PDCLIB_concat( _PDCLIB_assert_, __LINE__ ) = 1 / ( !!(e) ) }
    #endif
    

    对于给定表达式 e 消息m,这声明了一个匿名枚举,其中一个成员的名称为 _PDCLIB_assert_ 与当前源文件行串联( __LINE__ static_assert() 每个源文件)。此成员设置为 1 除以 如果表达式 电子 0 如果表达式为false,则会导致失败断言的输出如下:

    ./path/to/source.c:57:94: warning: division by zero [-Wdiv-by-zero]
     #define static_assert( e, m ) enum { _PDCLIB_concat( _PDCLIB_assert_, __LINE__ ) = 1 / ( !!(e) ) }
                                                                                          ^
    
    ./path/to/header.h:571:1: note: in expansion of macro 'static_assert'
     static_assert( false, "test" );
     ^
    ./path/to/source.c:57:62: error: enumerator value for '_PDCLIB_assert_571' is not an integer constant
    ...
    

    它不漂亮,但它完全符合C89标准,经过测试,并且可以使用。

    请随意重命名 _PDCLIB_* 你喜欢什么都行。

        2
  •  2
  •   Emanuele Paolini    6 年前

    #define static_assert(COND, MSG) extern int __static_assert_dummy__
    

    工作很好,但似乎丑陋的我!

        3
  •  2
  •   Lundin    6 年前

    因为这是一个C11特性,所以答案很简单:只需检查编译器是否支持C11。

    #if defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112
      static_assert(sizeof(my_stuct)==42, "check struct size");
    #endif 
    

    相反,要在没有标准C的情况下使其成为无操作,从而消除对上述编译器开关的需要,则如下所示:

    #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112
      #define static_assert(cond, str) struct dummy_t
    #endif 
    

    但你要记住 static_assert 要求 #include <assert.h> _Static_assert

        4
  •  2
  •   P.W    6 年前

    只是测试得很快,但是:

    #define static_assert(COND, MSG) extern int _no_static_assertion
    

    或者别的什么?重复 extern