101*_*010 9 c++ gcc clang static-members language-lawyer
考虑以下代码:
#include <iostream>
struct Foo {
static int const i = i + 1;
};
int main() {
std::cout << Foo::i << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
Clang 3.7版汇编了这个和输出1.
虽然GCC版本5.3发出错误:
错误:'i'未在此范围内声明
两个编译器中的哪一个符合C++标准?
GCC 抱怨名称未声明当然是错误的,因为声明点i紧接在其声明符之后。
然而,GCC 总体上拒绝该片段可以说是正确的。[类.静态.数据]/3 :
如果非易失性
const静态数据成员是整型或枚举类型,则其在类定义中的声明可以指定大括号或等于初始化程序 ,其中作为赋值表达式 的每个初始化程序子句都是常量表达式 (5.20) 。
为了使[expr.const]/(2.7)不失败,必须应用其四个子项目之一:
左值到右值的转换(4.1),除非它应用于
- 整型或枚举类型的非易失性泛左值,引用具有前面初始化的完整非易失性
const对象,并使用常量表达式进行初始化,或者- 引用字符串文字 (2.13.5) 的子对象的非易失性泛左值,或者
- 一个非易失性泛左值,它引用用 定义的非易失性对象
constexpr,或者引用此类对象的非可变子对象,或者- 文字类型的非易失性泛左值,引用其生命周期开始于 的求值内的非易失性对象
e;
(2.7.1) 是唯一合理的候选者,但由于i之前没有使用初始化器进行初始化,所以它不适用。
请注意,Clang 是完全一致的:
constexpr int i = i;
void f() {
// constexpr int j = j; // error
static constexpr int h = h;
}
Run Code Online (Sandbox Code Playgroud)
i如果它具有静态存储持续时间,则它似乎在其初始化程序中被视为“正确”初始化。我提交了错误#26858。
| 归档时间: |
|
| 查看次数: |
209 次 |
| 最近记录: |