gpt4 book ai didi

c++ - 为什么未诊断出在 constexpr 上下文中使用保留的标识符名称?

转载 作者:行者123 更新时间:2023-12-05 08:04:03 25 4
gpt4 key购买 nike

基于以下两条规则:

  • 使用以“_”+大写字母开头或包含双下划线的标识符是未定义的行为。
  • constexpr 表达式中不允许出现未定义的行为 -> 编译器不应编译。

那为什么编译器不提示这个呢?

constexpr int _UB() {return 1;}
int main() {
constexpr int a = _UB();
return a;
}

Demo

另外,我看到很多专业的、符合 MISRA 标准的代码似乎违反了这个命名规则,例如参见here :

#ifndef __STM32F732xx_H
#define __STM32F732xx_H

所有这些库是否也调用 UB?

最佳答案

Undefined behavior is not allowed in constexpr expressions -> compiler should not compile

比这更窄一点;根据 [expr.const]/5 , /5.7特别是:

An expression E is a core constant expression unless the evaluation of E, following the rules of the abstract machine ([intro.execution]), would evaluate one of the following:

  • [...]
  • /5.7 an operation that would have undefined behavior as specified in [intro] through [cpp];

现在,[intro] 通过 [cpp] 包括:

1 Scope[intro.scope]
2 Normative references[intro.refs]
3 Terms and definitions[intro.defs]
4 General principles[intro]
5 Lexical conventions[lex]
6 Basics[basic]
7 Expressions[expr]
8 Statements[stmt.stmt]
9 Declarations[dcl.dcl]
10 Modules[module]
11 Classes[class]
12 Overloading[over]
13 Templates[temp]
14 Exception handling[except]
15 Preprocessing directives[cpp]

然而,关于全局名称下划线的规则来自 [library],特别是 [reserved.names]/2[global.names]/1在 [library] 中,它不在“[intro] through [cpp]” 中。

[reserved.names]/2 If a program declares or defines a name in a context where it is reserved, other than as explicitly allowed by this Clause, its behavior is undefined.

[global.names]/1 Certain sets of names and function signatures are always reserved tothe implementation:

  • (1.1) Each name that contains a double underscore __ or begins with an underscore followed by an uppercase letter ([lex.key]) is reservedto the implementation for any use.
  • (1.2) Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace.

现在,[lex.name]/3还包括相同的标识符保留规则

In addition, some identifiers are reserved for use by C++ implementations and shall not be used otherwise; no diagnostic is required.

  • (3.1) Each identifier that contains a double underscore __ or begins with an underscore followed by an uppercase letter is reserved to theimplementation for any use.
  • (3.2) Each identifier that begins with an underscore is reserved to the implementation for use as a name in the global namespace.

违反 [lex.name]/3 是格式错误的,不需要诊断(IFNDR),这与未定义的行为不同;根据上面的 [expr.const]/5.7,一些 UB 应该实际上被诊断出来(constexpr 上下文)。

根据 [intro] 到 [cpp] [expr.const]/5.7 对 UB 的限制可以说是有意限制规则以避免构造对于典型的 C++ 实现者来说是 UB 而不是 STL 库实现者,例如[库]中的规则。这也可能是一个措辞缺陷,特别是当 [lex.name]/3 的规则仅在 [library] 中 [reserved.names]/2 的“事实之后”从 IFNDR 变为 UB 时。

因此,这种“种类”的未定义行为 (UB) 可以说不属于使表达式无法成为核心常量表达式的 UB。

关于c++ - 为什么未诊断出在 constexpr 上下文中使用保留的标识符名称?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70244992/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com