#include <memory>
int main() {
constexpr auto v = [] {
std::allocator<char> a;
auto x = a.allocate(10);
x[2] = 1;
auto r = x[2];
a.deallocate(x, 10);
return r;
}();
return v;
}
程序格式是否错误? Clang 这么认为,GCC 和 MSVC 不这么认为:https://godbolt.org/z/o3bcbxKWz https://godbolt.org/z/o3bcbxKWz
删除constexpr
我认为该程序的格式并不错误,并且具有明确定义的行为:
By [分配器.成员]/5 https://timsong-cpp.github.io/cppwp/n4868/allocator.members#5电话a.allocate(10)
开始生命周期char[10]
它为其分配存储空间的数组。
根据[介绍对象]/13 https://timsong-cpp.github.io/cppwp/n4868/intro.object#13开始类型数组的生命周期char
隐式创建对象在其存储中。
标量类型,例如char
are 隐式生命周期类型. ([基本.类型.一般]/9 https://timsong-cpp.github.io/cppwp/n4868/basic.types.general#9
[介绍对象]/10 https://timsong-cpp.github.io/cppwp/n4868/intro.object#10然后说类型的对象char
是在存储中创建的char[10]
数组(及其生命周期开始)如果可以给程序定义的行为。
在没有开始生命周期的情况下char
对象于x[2]
,程序没有constexpr
由于写入,会有未定义的行为x[2]
在其生命周期之外,但是char
由于上述参数,可以隐式创建对象,从而使程序行为明确定义为以状态退出1
.
With constexpr
,我想知道该程序是否格式错误。隐式对象创建是否适用于常量表达式?
根据[介绍对象]/10 https://timsong-cpp.github.io/cppwp/n4868/intro.object#10隐式创建对象以赋予程序定义的行为,但是不规范是否算作定义的行为呢?
如果不是,那么程序不应该因为隐式创建而导致格式错误。char
对象为x[2]
.
如果是,那么下一个问题是是否未指定该程序是否格式错误,因为[介绍对象]/10 https://timsong-cpp.github.io/cppwp/n4868/intro.object#10还表示,如果多个集合可以给程序提供定义的行为,则未指定隐式创建哪些对象。
从语言设计的角度来看,我希望隐式对象创建不应该发生在常量表达式中,因为验证一组对象的(不)存在使常量表达式有效对于一般编译器来说可能是不可行的。