问题
In this article from Guru of the week, it is said: It is illegal to #define a reserved word.
Is this true? I can’t find anything in the norm, and I have already seen programmers redefining new, for instance.
回答1:
17.4.3.1.1 Macro names [lib.macro.names]
1 Each name defined as a macro in a header is reserved to the implementation for any use if the translation unit includes the header.164)
2 A translation unit that includes a header shall not contain any macros that define names declared or defined in that header. Nor shall such a translation unit define macros for names lexically identical to keywords.
By the way, new
is an operator and it can be overloaded (replaced) by the user by providing its own version.
回答2:
The corresponding section from C++11:
17.6.4.3.1 Macro names [macro.names]
1 A translation unit that includes a standard library header shall not #define or #undef names declared in any standard library header.
2 A translation unit shall not #define or #undef names lexically identical to keywords.
Paragraph 1 from C++03 has been removed. The second paragraph has been split in two. The first half has now been changed to specifically state that it only applies to standard headers. The second point has been broadened to include any translation unit, not just those that include headers.
However, the Overview for this section of the standard (17.6.4.1 [constraints.overview]) states:
This section describes restrictions on C++ programs that use the facilities of the C++ standard library.
Therefore, if you are not using the C++ standard library, then you're okay to do what you will.
So to answer your question in the context of C++11: you cannot define (or undefine) any names identical to keywords in any translation unit if you are using the C++ standard library.
回答3:
Here's a little thing you can do if you don't want someone to use goto's. Just drop the following somewhere in his code where he won't notice it.
#define goto { int x = *(int *)0; } goto
Now every time he tries to use a goto statement, his program will crash.
回答4:
They're actually wrong there, or at least doesn't tell the whole story about it. The real reason it's disallowed is that it violates the one-definition-rule (which by the way is also mentioned as the second reason why it's illegal).
To see that it's actually allowed (to redefine keywords), at least if you don't use the standard libraries, you have to look at an entirely different part of the standard, namely the translation phases. It says that the input is only decomposed into preprocessor tokens before preprocessing takes place and looking at those there's no distinction between private
and fubar
, they are both identifiers
to the preprocessor. Later when the input is decomposed into token
the replacement has already taken place.
It has been pointed out that there's a restriction on programs that are to use the standard libraries, but it's not evident that the example redefining private
is doing that (as opposed to the "Person #4: The Language Lawyer" snippet which uses it for output to cout
).
It's mentioned in the last example that the trick doesn't get trampled on by other translation units or tramples on other. With this in mind you should probably consider the possibility that the standard library is being used somewhere else which will put this restriction in effect.
回答5:
It's not as far as I'm aware illegal - no compiler I've come across yet will generate an error if you do
#define true false
#defining
certain keywords are likely to generate errors in compilation for other reasons. But a lot of them will just result in very strange program behaviour.
来源:https://stackoverflow.com/questions/9109377/is-it-legal-to-redefine-a-c-keyword