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

Print a deprecation warning when using a macro in a #if statement

我想弃用一个宏,即使在 #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 时除外?)。谢谢大家。

I want to deprecate a macro in such a way that it will print a nice warning even if used inside of a #if statement.

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

建议的事情

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

The standard is unclear on where a _Pragma operator can appear. The preprocessor does not accept it within a preprocessing conditional directive like ‘#if’. To be safe, you are probably best keeping it out of directives other than ‘#define’, and putting it on a line of its own.

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

正如@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 中是不可能的)。