重新定义 C++ 是否合法?关键词?
在本周大师的这篇文章中,据说:#define 保留的内容是非法的
这是真的吗?我在规范中找不到任何东西,例如,我已经看到程序员重新定义了新的东西。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
17.4.3.1.1 宏名称 [lib.macro.names]
顺便说一下,
new
是一个运算符,用户可以通过提供来重载(替换)它它自己的版本。17.4.3.1.1 Macro names [lib.macro.names]
By the way,
new
is an operator and it can be overloaded (replaced) by the user by providing its own version.C++11 中的相应部分:
17.6.4.3.1 宏名称 [macro.names]
C++03 中的第 1 段已被删除。第二段被分成两段。前半部分现已更改为明确声明它仅适用于标准标头。第二点已扩大到包括任何翻译单元,而不仅仅是那些包含标题的单元。
但是,标准此部分的概述 (17.6.4.1 [constraints.overview]) 指出:
因此,如果您不使用 C++ 标准库,那么您可以做您想做的事情。
因此,要在 C++11 的上下文中回答您的问题:如果您使用的是 C++ 标准库,则无法定义(或取消定义)与任何翻译单元中的关键字相同的任何名称。
The corresponding section from C++11:
17.6.4.3.1 Macro names [macro.names]
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:
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.
他们实际上错了,或者至少没有讲述整个故事。它被禁止的真正原因是它违反了单一定义规则(顺便说一句,这也被称为非法的第二个原因)。
要看到它实际上是允许的(重新定义关键字),至少如果您不使用标准库,您必须查看标准的完全不同的部分,即翻译阶段。它表示输入仅在进行预处理之前分解为预处理器标记,并且查看这些标记,
private
和fubar
之间没有区别,它们都是标识符 到预处理器。稍后,当输入被分解为
token
时,替换已经发生。有人指出,使用标准库的程序受到限制,但重新定义
private
的示例是否这样做并不明显(与“Person #4:语言”相对) Lawyer”片段,使用它输出到cout
)。在最后一个例子中提到,该技巧不会被其他翻译单元践踏或践踏其他翻译单元。考虑到这一点,您可能应该考虑标准库在其他地方使用的可能性,这将使此限制生效。
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
andfubar
, they are bothidentifiers
to the preprocessor. Later when the input is decomposed intotoken
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 tocout
).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.
如果您不希望别人使用 goto,您可以执行以下操作。只需将以下内容放在他的代码中他不会注意到的地方即可。
现在,每次他尝试使用 goto 语句时,他的程序都会崩溃。
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.
Now every time he tries to use a goto statement, his program will crash.
据我所知,这并不是非法的 - 如果您执行
#defining
,我遇到的编译器都不会生成错误,某些关键字可能会因其他原因在编译中生成错误。但其中很多只会导致非常奇怪的程序行为。It's not as far as I'm aware illegal - no compiler I've come across yet will generate an error if you do
#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.