C++预处理器 #define-ing 关键字。是否符合标准?

发布于 2024-08-30 17:05:32 字数 298 浏览 2 评论 0原文

帮助解决评论中正在进行的争论 这个关于 bool 和 1 的问题

符合标准的 C++ 预处理器是否允许使用 #define 重新定义语言关键字?如果是这样,符合标准的 C++ 预处理器是否必须允许这样做?

如果一个 C++ 程序重新定义了一个语言关键字,那么该程序本身是否符合标准?

Help settle the debate that's going on in the comments at this question about bool and 1:

Can a standards-conforming C++ preprocessor allow one to use #define to redefine a language keyword? If so, must a standards-conforming C++ preprocessor allow this?

If a C++ program redefines a language keyword, can that program itself be standards conforming?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(3

∝单色的世界 2024-09-06 17:05:32

在 C++ 中,与禁止 #define 关键字最接近的是 §17.4.3.1.1/2,它仅在包含标准库头的翻译单元中禁止使用该关键字:

包含标头的翻译单元不应包含任何定义在该标头中声明或定义的名称的宏。这样的翻译单元也不能为与关键字词法相同的名称定义宏。

该段落的第二句已在 C++0x 中更改为完全禁止 #define 关键字(C++0x FCD §17.6.3.3.1):


翻译单元不应#define 或#undef 名称在词法上与关键字相同。

编辑: 正如 Ken Bloom 在 对其答案的评论,C++0x中的规则没有改变;文本刚刚被重新排列,以迷惑像我这样的人。 :-)

In C++, the closest thing to forbidding #defineing a keyword is §17.4.3.1.1/2, which only disallows it in a translation unit that includes a standard library header:

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.

The second sentence of that paragraph has been changed in C++0x to outright forbid #defineing a keyword (C++0x FCD §17.6.3.3.1):

A translation unit shall not #define or #undef names lexically identical to keywords.

Edit: As pointed out by Ken Bloom in comments to his answer, the rules have not changed in C++0x; the text has just been rearranged to confuse people like me. :-)

洒一地阳光 2024-09-06 17:05:32

根据 C++11 [macro.names],这是不允许的:

翻译单元不得使用与关键字、表 3 中列出的标识符或 7.6 中描述的属性标记在词法上相同的 #define#undef 名称.

“表3中列出的标识符”是finaloverride;属性标记是 [[fallthrough]] 中的标识符,依此类推。

最新标准中也仍然存在该条款。

It is not permitted, according to C++11 [macro.names]:

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.

The "identifiers listed in Table 3" are final and override; and the attribute-tokens are the identifiers in [[fallthrough]] and so on.

This clause is still in the latest standard too.

倦话 2024-09-06 17:05:32

根据 2005-10-19 C++ 工作草案进行工作 (因为我没有方便的标准):

第 16.3 节将 #define 的语法定义为 #defineidentifier replacement-list-newline (对象-类宏)或以#defineidentifier lparen 开头的几种结构之一(类函数宏)。 identifier 在第 2.10 节中定义为 identifier-nondigit |标识符 非数字 | 标识符标识符数字。第 2.11 节指出,在编译的第 7 阶段(第 2.1 节)中,某些标识符被无条件地视为关键字,因此我得出的结论是,它们因此在第 4 阶段(即预处理器扩展)中没有被特殊对待。 因此,该标准似乎要求预处理器允许您重新定义语言关键字(第 2.11 节中列出)

然而,预处理器有一个自己的关键字,即define,以及预定义宏的列表(第16.8节)。第 16.8 节指出,如果重新定义它们,则行为是未定义的,但并不禁止预处理器将它们识别为宏名称。

Working from the 2005-10-19 C++ working draft (since I don't have a standard handy):

Section 16.3 defines the grammar for #define to be #define identifier replacement-list-newline (object-like macros) or one of several constructions beginning with #define identifier lparen (function-like macros). identifiers are defined in section 2.10 to be identifier-nondigit | identifier identifier-nondigit | identifier digit. Section 2.11 indicates that a certain list of identifiers are unconditionally treated as keywords in phase 7 of compilation (section 2.1), and I conclude that they are therefore not treated specially in phase 4, which is preprocessor expansion. Thus, it appears that the standard requires the preprocessor to allow you to redefine language keywords (listed in Section 2.11).

However, the preprocessor has a keyword of its own, namely defined, as well as a list of predefined macros (Section 16.8). Section 16.8 states that the behavior is undefined if you redefine these, but does not prohibit the preprocessor from recognizing these as macro names.

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