发出参数化 _Pragma 语句?

Emitting parameterized _Pragma statements?

发出 #pragma 指令来抑制和恢复警告通常是不受欢迎的,但有时是不可避免的。一些编译器支持 _Pragma 作为一种从宏表达式内部控制诊断的方法。

讨论了如何将单个字符串粘贴到 _Pragma 语句中。

有什么方法可以参数化这个吗?我想将两个 _Pragma 指令组合在一个宏后面,但这需要在 _Pragma 语句内将标记粘贴在一起:

#define DO_A_THING(SOME_FLOAT) \
  do { \
    DISABLE_COMPILER_WARNING(double-promotion) \
    call_variadic_function("blah", SOME_FLOAT) \
    RESTORE_COMPILER_WARNING() \
  } while(0)

DISABLE_COMPILER_WARNING 会扩展为:

    _Pragma("GCC diagnostic push") \
    _Pragma("GCC diagnostic ignored \"-Wdouble-promotion\"")

RESTORE_COMPILER_WARNING 会扩展成如下内容:

    _Pragma("GCC diagnostic pop")

有没有办法让创作者DISABLE_COMPILER_WARNING按照所写内容进行扩展?

作品:

// double expand for proper "something \"something\""
#define PRAGMA_DO1(X) _Pragma(#X)
#define PRAGMA_DO(X) PRAGMA_DO1(GCC diagnostic ignored #X)

#define DISABLE_COMPILER_WARNING(X) \
    _Pragma("GCC diagnostic push") \
    PRAGMA_DO(-W##X)

#define RESTORE_COMPILER_WARNING()  \
    _Pragma("GCC diagnostic pop")
    
#define DO_A_THING(SOME_FLOAT) \
  do { \
    DISABLE_COMPILER_WARNING(double-promotion) \
    call_variadic_function("blah", SOME_FLOAT); \
    RESTORE_COMPILER_WARNING() \
  } while(0)

void call_variadic_function(const char *str, ...);

int main() {
    // call_variadic_function("blah", (float)1);
    DO_A_THING((float)1);
}