C++ Logo

std-discussion

Advanced search

Re: Undefining a compiler 's predefined macro

From: Andrew Schepler <aschepler_at_[hidden]>
Date: Sun, 22 Mar 2020 10:41:06 -0400
>
> Is undefining a predefined macro "using" the macro ?
> Probably, but the imprecise meaning of the term "used otherwise" can
> certainly be improved in that note.
>

I can actually see this argument. [lex.name]/1 describes "identifier" as an
element of the grammar used in translation phase 3, one type of
preprocessing-token. But then [lex.name]/2 discusses the grammar used in
translation phase 7, where "identifier" is one type of token. Technically
these two meanings of "identifier" are two separate things. So which do the
restrictions of [lex.name]/3 apply to?

If we say they restrict what appears in the translation unit immediately
when preprocessing-tokens are first formed in phase 3, a use with #undef is
forbidden, but then we might wonder about preprocessing-tokens formed by ##
concatenation in phase 4. If we say they only restrict identifiers as phase
7 tokens, a use with #undef would be fine since preprocessing directives
are deleted at the end of phase 4. Probably the intent is to restrict both
kinds, but yes, I'm not exactly concluding that from the text.

Turning to the practical, though. As with any undefined behavior, an
implementation is free to define what it actually does, so that a program
with undefined behavior is fine with that compiler, just less portable.
Whatever you're trying to do is certainly not portable, so possibly the
compiler's documentation and usage guides are a more appropriate source
than the C++ Standard for a practical answer to this in the first place. If
its documentation says you can undefine the macro, go ahead. I'm not aware
of any such allowed case, though.

If it's not documented as allowed, it should probably be avoided. Usually
the purpose of predefined macros is to describe how the compiler behaves,
in general or because of current settings, or to hook into an
implementation custom feature. If you undefine a behavior description
macro, that most likely won't change the actual compiler behavior it
describes, so there could be a chance some code in the implementation's
Standard library or other code counting on the macro test now does
something wrong. Also, because of those purposes, and given the restriction
stated by the Standard, a compiler (possibly a future version of your own
compiler) would be in its rights to treat its own meaningful reserved
identifier in a special built-in way, possibly to the point of essentially
ignoring the #undef and always forcing uses of the macro to give the
built-in behavior, including a defined() result of 1.

Received on 2020-03-22 09:44:16