【问题标题】:Is there a way to force C preprocessor to evaluate macro arguments before the macro有没有办法强制 C 预处理器在宏之前评估宏参数
【发布时间】:2016-05-08 22:21:03
【问题描述】:

我有许多格式为

的宏
#define F(A,B)   Some function of A and B

为了便于阅读,我想为这些宏定义参数,例如

#define C A,B

所以我可以说

F(C)

但是预处理器试图在 C 之前扩展 F 并抱怨 F 需要 2 个参数。有没有办法让它在扩展F之前扩展C,这样就不会发生错误?

【问题讨论】:

  • 天哪,你不应该这样做。
  • 我不明白有些人对预处理器的痴迷。只需将它用于简单的东西。编译器要好得多 - 它为初学者提供了类型安全性
  • 如果你需要,从其他东西生成你的 C 代码。也许使用其他一些预处理器(例如m4gpp);这不是标准 C 预处理器的工作
  • @EdHeal 是的,我同意。我什至避免使用非宏变量函数。不过还是忍不住不回答。
  • 在宏观问题中大声笑“为了可读性”:)

标签: c macros


【解决方案1】:

您可以使用带有可变数量参数的中间宏:

#define F1(A,B) 
#define F(...) F1(__VA_ARGS__)

#define C A,B

int main(void) {
    F(C)
    F(1,2)
    return 0;
}

这应该可以编译。如果您传递的参数多于或少于两个,或者未扩展为恰好两个参数,您仍然会遇到编译失败。

【讨论】:

    【解决方案2】:

    宏扩展(错误地)不会触发参数重新计数。因此,任何时候函数调用的宏扩展导致不同数量的参数,都必须强制重新计算参数的数量。

    在调用之前使用此模式强制扩展和重新计数:

    //Step 1: wrap the entire affected argument pack in parenthesis
    #define mFn(A, ExpandingArgument) mFn1((A, ExpandingArgument))
    
    //Step 2: intermediary layer without ## or # is required to actually expand
    #define mFn1(...) mFn2(__VA_ARGS__)
    
    //Step3: Paste the parenthesized arguments to final function identifier to trigger 
    //       function like macro interpretation and invocation
    #define mFn2(...) mFn3##__VA_ARGS__
    
    //Step4: Implement the actual function as if the standard were written correctly
    #define mFn3(A,B,C,...) //Do things
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-22
      • 1970-01-01
      • 2020-05-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多