Is it undefined behavior to #define/#undef an identifier with special meaning?

那年仲夏 提交于 2020-01-14 07:15:49

问题


An answer to the question Disable check for override in gcc suggested using -Doverride= on the command line to disable errors for erroneous use of override, which is effectively the same as adding:

#define override

to the source file.

My initial reaction was that this seems like undefined behavior since we are redefining a keyword but looking at the draft C++11 standard section 2.12 Keywords [lex.key] I was surprised that neither override nor final are keywords. They are covered in the previous section 2.11 [lex.name] which says they are identifiers with special meaning:

The identifiers in Table 3 have a special meaning when appearing in a certain context[...]

and Table 3 is labelled Identifiers with special meaning and includes both override and final.

The question is, is it undefined behavior to redefine(using #define) identifiers with special meaning? Are they treated any differently than keywords in this respect?


回答1:


If you are using the C++ standard library it is undefined behavior to redefine identifiers with special meaning, this also applies to keywords. From the draft C++11 standard under section 17.6.4 [constraints] we have section 17.6.4.1 [constraints.overview] which says:

This section describes restrictions on C++ programs that use the facilities of the C++ standard library [...]

and under 17.6.4 we have section 17.6.4.3.1 [macro.names] which says:

A translation unit shall not #define or #undef names lexically identical to keywords, to the identifiers listed in Table 3, or to the attribute-tokens described in 7.6.

Table 3 list the Identifiers with special meaning. We can see this paragraph also covers keywords and they are treated in the same manner.




回答2:


Implementations' standard header files are allowed to "implement" standard functions using macros in cases where a macro could meet the requirements for the function (including ensuring that arguments are evaluated exactly once). Further, such macros are allowed to make use of keywords or identifiers whose behavior is specified in in the standard or "reserved to the implementation"; use of such macros in contexts where the keywords or identifiers have been redefined could have arbitrary effects.

That having been said, the historical interpretation of this form of UB would be to say that compilers shouldn't go out of their way to cause wacky behavior, and outside of "pedantic modes" should allow user code to assign meanings to reserved identifiers the compiler would otherwise not use. This can be helpful in cases where code should be usable both on compilers which would require a keyword like __packed, and on compilers which neither recognize nor require such a keyword.). Redefining keywords in the fashion you're doing is a bit dodgier; it will probably work, but there's a significant likelihood that that it will disrupt the behavior of a standard-library macro.



来源:https://stackoverflow.com/questions/30311551/is-it-undefined-behavior-to-define-undef-an-identifier-with-special-meaning

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!