在 constexpr 构造函数中按引用传递 std::array 会导致数据指针为 null

Passing std::array by reference in constexpr constructor results in null data pointer

提问人:Lukas Vozenilek 提问时间:12/14/2022 最后编辑:Lukas Vozenilek 更新时间:12/14/2022 访问量:92

问:

我的类有一个 constexpr 构造函数,它引用了 .当创建我的类的全局 constexpr 常量并传递一个即时数组时,构造函数会从数组引用中获取一个空数据指针,即使基础数据存在:std::array

class MyClass {
public:
    explicit constexpr MyClass(const std::array<int, 3> &from) {
        assert(from[0] == 1);           // Ok
        assert(from[1] == 2);           // Ok
        assert(from[2] == 3);           // Ok
        assert(from.data() != nullptr); // Compilation halts here
    }
};

static constexpr MyClass constGlobal{std::array{1, 2, 3}};

需要 C++ 17+

测试于:

明GW w64 9.0

ARM gcc 12.2 版本

我希望指针存在,因为工作得很好。data()operator[]

编辑:

指针确实存在。这似乎是 GCC 不允许将指针与临时对象进行比较的问题。仍然存在一个相关的问题,这个简化的例子试图描述(很糟糕)。data()

这是根本问题

编辑:

看起来这可能是在constexpr上下文中比较临时地址的gcc错误:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85944

C++ GCC std constexpr stdarray

评论

0赞 πάντα ῥεῖ 12/14/2022
assert()用于运行时,需要在编译时解析。请考虑一下。constexprstatic_assert()
0赞 463035818_is_not_an_ai 12/14/2022
您收到什么编译器错误消息?这里 gcc 非常清楚无法评估断言 godbolt.org/z/csneWo546,即问题不在于指针是 nullptr。它唯一在代码中有问题的断言
1赞 Homer512 12/14/2022
适用于 MSVC 19.30,请参阅 Godbolt 也适用于 Clang.In godbolt 代码 我将比较结果分配给布尔值。这在 GCC 上给出了不同的错误。
0赞 Lukas Vozenilek 12/14/2022
@Homer512 设置存储在类中的标志会导致以下 GCC 错误:“...不是一个常量表达式,因为它指的是一个未完全初始化的变量”
1赞 Artyer 12/14/2022
问题似乎出在 constexpr 评估期间 gcc 不喜欢将 (address-of-temporary-object) 与 nullptr 进行比较:<godbolt.org/z/z9bhGjKcd>。似乎是 GCC 错误。隐约相似的问题:stackoverflow.com/q/39405241

答: 暂无答案