隐式对象创建是否适用于常量表达式?

2024-01-22

#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还表示,如果多个集合可以给程序提供定义的行为,则未指定隐式创建哪些对象。


从语言设计的角度来看,我希望隐式对象创建不应该发生在常量表达式中,因为验证一组对象的(不)存在使常量表达式有效对于一般编译器来说可能是不可行的。


2469. 隐式对象创建与常量表达式 https://wg21.cmeerw.net/cwg/issue2469

隐式对象创建(如 6.7.2 [intro.object] 第 10 段中所述)不应在常量表达式求值期间发生,但目前没有任何措辞禁止这样做。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

隐式对象创建是否适用于常量表达式? 的相关文章

随机推荐