Luke Yeager Luke Yeager - 4 days ago 4
C Question

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

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.

This answer is very nearly what I want, but it throws an error when the macro is accessed from within a
#if
statement.

#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
}


The error is:

error: missing binary operator before token "("


Bonus points if you can find me a cross-platform compatible solution!

EDIT

I'm trying to handle a breaking change in a library gracefully - I want users to have a nice, clear warning (or error) whenever they use an old macro, so it will be clear that they need to migrate their code to using the new macro. These pragma solutions only work if the value of that constant is used in code, not if the value is accessed in a preprocessor directive.

According to the answers provided below, it seems like there's not a solution to this problem (except possibly when using clang?). Thanks, everyone.

Answer

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.

I was going to suggest the comma operator, but that doesn't seem to work because the _Pragma macro probably yields no real code. Also, gcc, at least, explicitly says you can't do what you suggested with _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 didn't error on your program and gave the warnings you want ...