重新定义 C++ 是否合法?关键词?

发布于 2025-01-01 06:26:18 字数 139 浏览 1 评论 0原文

在本周大师的这篇文章中,据说:#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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

溺深海 2025-01-08 06:26:18

17.4.3.1.1 宏名称 [lib.macro.names]

1 如果翻译单元包含标头,则标头中定义为宏的每个名称都保留给实现以供任何使用。164)
2 包含标头的翻译单元不应包含任何定义该标头中声明或定义的名称的宏。 这样的翻译单元也不能为与关键字词法相同的名称定义宏。

顺便说一下,new 是一个运算符,用户可以通过提供来重载(替换)它它自己的版本。

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.

怀里藏娇 2025-01-08 06:26:18

C++11 中的相应部分:

17.6.4.3.1 宏名称 [macro.names]

1 包含标准库头的翻译单元不得在任何标准库头中声明 #define 或 #undef 名称。
2 翻译单元不得 #define 或 #undef 名称在词法上与关键字相同。

C++03 中的第 1 段已被删除。第二段被分成两段。前半部分现已更改为明确声明它仅适用于标准标头。第二点已扩大到包括任何翻译单元,而不仅仅是那些包含标题的单元。

但是,标准此部分的概述 (17.6.4.1 [constraints.overview]) 指出:

本节介绍对使用 C++ 标准库功能的 C++ 程序的限制。

因此,如果您不使用 C++ 标准库,那么您可以做您想做的事情。

因此,要在 C++11 的上下文中回答您的问题:如果您使用的是 C++ 标准库,则无法定义(或取消定义)与任何翻译单元中的关键字相同的任何名称。

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.

甜味拾荒者 2025-01-08 06:26:18

他们实际上错了,或者至少没有讲述整个故事。它被禁止的真正原因是它违反了单一定义规则(顺便说一句,这也被称为非法的第二个原因)。

要看到它实际上是允许的(重新定义关键字),至少如果您不使用标准库,您必须查看标准的完全不同的部分,即翻译阶段。它表示输入仅在进行预处理之前分解为预处理器标记,并且查看这些标记,privatefubar 之间没有区别,它们都是标识符 到预处理器。稍后,当输入被分解为 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 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.

执手闯天涯 2025-01-08 06:26:18

如果您不希望别人使用 goto,您可以执行以下操作。只需将以下内容放在他的代码中他不会注意到的地方即可。

#define goto { int x = *(int *)0; } 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.

#define goto { int x = *(int *)0; } goto

Now every time he tries to use a goto statement, his program will crash.

心的位置 2025-01-08 06:26:18

据我所知,这并不是非法的 - 如果您执行

#define true false

#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

#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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文