2

What is the motivation / rationale behind not macro-expanding arguments of #error (and #warning) directive?

The gcc documentation explicitly states:

Neither ‘#error’ nor ‘#warning’ macro-expands its argument.

P.S. For #warning (not standardized) the fix is to use #pragma message (https://stackoverflow.com/a/12638158/1778275), which (normally) macro-expands its arguments.

UPD. The question is not specifically about why gcc does not perform macro-expantion. The quote from gcc documentation is used as an example of text, which explicitly states that neither #error nor #warning macro-expands its argument. I could not find this (or similar) text in C standard. Hence, refer the quite from gcc documentation.

UPD2. In comparison with #error the #include performs macro-expantion of its arguments. Quote from the standard (ISO/IEC 9899:202x (E)):

The preprocessing tokens after include in the directive are processed just as in normal text. (Each identifier currently defined as a macro name is replaced by its replacement list of preprocessing tokens.)

pmor
  • 5,392
  • 4
  • 17
  • 36
  • Since that is GCC documentation, the motivation for `#error` is of course that it is conforming to the C standard, which specifies this in C 2018 6.10.5. Presumably you then want to know why the C standard does not specify any expansion for those tokens. – Eric Postpischil Feb 12 '21 at 12:02
  • I'm not sure if there's much of a rationale behind any of it. A lot of stuff originating from back in C89 was just added to the language at a whim. Like, who could have guessed that when writing something like `#if FOO != BAR #error FOO is not BAR`, I might be also be interested in knowing the values of FOO and BAR... – Lundin Feb 12 '21 at 12:20
  • The C standard does not preclude the error message not have the contents expanded **as well**, it just requires that a message without the contents expanded is produced. – Antti Haapala -- Слава Україні Feb 12 '21 at 12:20
  • As for `#warning`, the rationale supposedly is that if you change `#error` to `#warning` its behaviour wouldn't change other than it outputting a message with slightly different format and not terminating compilation. `#warning` is *not* in the standard. – Antti Haapala -- Слава Україні Feb 12 '21 at 12:22

1 Answers1

2

I don't say this is the motivation for the standard, but thinking of many of my uses of #error it would be inconvenient to have it macro-expanded.
Admittedly, my habits might have been formed by the non-expansion.

#define MINIMUMCONFIG 1
#ifndef IMPORTANTCONFIG
#error  IMPORTANTCONFIG is undefined!
#error
#if     IMPORTANTCONFIG < MINIMUMCONFIG
#error  IMPORTANTCONFIG lower than MINIMUMCONFIG !
#endif
Yunnosch
  • 26,130
  • 9
  • 42
  • 54