【问题标题】:C Preprocessor Remove Trailing CommaC 预处理器删除尾随逗号
【发布时间】:2017-01-10 13:04:45
【问题描述】:

我有一个这样的宏:

#define C( a... ) ( char *[] ){ a, 0 }

这适用于非空参数:

C( "a", "b" ) => ( char *[] )( "a", "b", 0 }

但我想在提供空参数时删除尾随逗号:

C() => ( char *[] ){ , 0 }

这可能吗?

【问题讨论】:

  • 目前没有可移植的方式来做到这一点。 (不过,我相信有一个待定提案可以让你构建这样的东西。)
  • 我的意思是,看看 Boost.Preprocessor,也许有 某种 类的魔法可以实现这一点。 (这也应该在 C 中工作。)
  • 嗯,没关系,我只是好奇这是否可能。既然不是,我就定义类似#define C0 ( char *[] ){ 0 }
  • 不要删除尾随逗号,而是首先不要添加它。请参阅我的策略:How to easily create fully “variadic” functions with C++ 98 standard?。

标签: c gcc c-preprocessor


【解决方案1】:

至少在 GCC 5.4.0 中,在 Cygwin (default -std=gnu11) 上,这似乎可以满足您的要求(假设我正确理解您的问题):

#define C( a... ) ( char *[] ){ a 0 }
                                 ^ no comma!    
C( "a", "b", ) 
           ^ comma here
=> ( char *[] )( "a", "b", 0 }

C() 
=> ( char *[] ){ 0 }

使用gcc -E 进行测试,没有其他命令行选项。

编辑 正如@KerrekSB 所指出的,这是不可移植的。 GCC preprocessor docs 有这个说法(强调):

上面的解释对于唯一的宏参数是可变参数参数的情况是模棱两可的[as in this situation-Ed.],因为试图区分是否没有参数是没有意义的all 是空参数或缺少参数。在这种情况下,C99 标准清楚地表明逗号必须保留,但是现有的 GCC 扩展用于吞下逗号。 因此,CPP 在符合特定 C 标准时保留逗号,否则将其删除。

所以上述在 GCC 中运行良好,但可能不适用于其他编译器。但是,它确实适用于gcc -std=c90 -E(或c99,或c11)。

【讨论】:

  • 在每次调用宏时都必须输入尾随逗号,这在美学意义上是一个小麻烦,个人而言这并不值得,但从技术上讲,这似乎是唯一的(目前)这个问题的实际解决方法。
【解决方案2】:

查看 GCC 的 __VA_OPT__() 函数宏,它可以在 variadic macro 中使用。

#define C(...) (char *[]) { __VA_ARGS__ __VA_OPT__(,) 0 }

C("a", "b");   expands to (char *[]) { "a", "b" , 0 };
C();           expands to (char *[]) { 0 };

仅当__VA_ARGS__ 非空时,传递给__VA_OPT__() 的参数才会被扩展。

【讨论】:

    猜你喜欢
    • 2021-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-13
    • 1970-01-01
    • 2021-05-16
    • 1970-01-01
    相关资源
    最近更新 更多