在#if语句中使用宏时打印弃用警告

时间:2017-06-20 01:18:38

标签: c preprocessor pragma

我想弃用一个宏,即使在#if语句中使用它也会打印一个很好的警告。

This answer几乎是我想要的,但是当从#if语句中访问宏时会抛出错误。

#include <stdio.h>

#define DEPRECATED_CONSTANT _Pragma ("GCC warning \"Deprecated constant!\"") 0
#define DEPRECATED_FUNCTION(...) _Pragma ("GCC warning \"Deprecated function!\"") printf(__VA_ARGS__)

int main() {
    // Prints a warning (good)
    int n = DEPRECATED_CONSTANT;

    // Prints a warning (good)
    DEPRECATED_FUNCTION("%d\n", n);

// Throws an error (bad)
#if DEPRECATED_CONSTANT
    return 1;
#else
    return 2;
#endif
}

错误是:

error: missing binary operator before token "("

如果您能找到跨平台兼容的解决方案,可以获得积分!

修改

我试图优雅地处理库中的重大变化 - 我希望用户在使用旧宏时有一个很好的,明确的警告(或错误),因此很明显他们需要迁移他们使用新宏的代码。这些pragma解决方案仅在代码中使用该常量的值时才有效,而不是在预处理器指令中访问该值时。

根据下面提供的答案,似乎没有解决这个问题的方法(除非可能使用clang?)。谢谢,大家。

2 个答案:

答案 0 :(得分:4)

  

我想以这样一种方式弃用一个宏,它会打印一个很好的   即使在#if语句中使用也会发出警告。

我打算建议逗号运算符,但这似乎不起作用,因为_Pragma宏可能不会产生真正的代码。此外,gcc至少明确表示你不能用_Pragma():

做你的建议

https://gcc.gnu.org/onlinedocs/cpp/Pragmas.html

  

标准不清楚_Pragma运算符的出现位置。的的   预处理器在预处理条件中不接受它   像'#if'这样的指令。为了安全起见,你可能最好把它保留下来   除了'#define'之外的指令,并把它放在它的一行上   自己的。

PS - clang 8.1.0在您的程序中没有出错并给出了您想要的警告......

答案 1 :(得分:1)

正如@ jschultz410所提到的,你在gcc中明确禁止你所做的事情(见https://gcc.gnu.org/onlinedocs/cpp/Pragmas.html)。

嵌套宏似乎适合这种用例:

#include <stdio.h>

#define DEPRECATED_CONSTANT_VALUE 0
#define DEPRECATED_CONSTANT _Pragma ("GCC warning \"Deprecated constant!\"") DEPRECATED_CONSTANT_VALUE
#define DEPRECATED_FUNCTION(...) _Pragma ("GCC warning \"Deprecated function!\"") printf(__VA_ARGS__)

int main() {
    // Prints a warning (good)
    int n = DEPRECATED_CONSTANT;

    // Prints a warning (good)
    DEPRECATED_FUNCTION("%d\n", n);

// Throws an error (bad)
#if DEPRECATED_CONSTANT_VALUE
    return 1;
#else
    return 2;
#endif
}

是的,这有点粗糙,但在预处理器逻辑领域,我们已经放弃了任何一种设计优雅。至少这种方式宏接口在非预处理器代码中维护。 (是的,这不会在#if语句中打印预处理器警告,但遗憾的是gcc不可能这样做。