consteval构造对象的地址是否为常量表达式?Clang编译行为存疑
问题分析:Clang拒绝
consteval构造函数中使用this赋值的代码 编辑说明:此问题已作为LLVM Bug提交。
以下代码可在GCC和MSVC中编译通过,但会被Clang拒绝:
struct X { const void *p_; consteval X() : p_{this} { } }; static constexpr X x{};
核心问题
Clang的行为是否正确?
我的理解是x{}是构造函数的立即调用,在其函数体内,static constexpr变量的地址应是已知的常量值。某相似问题的回答表明,对同一表达式中创建的对象调用成员函数是合法的,这让我更有理由认为此场景下this是有效的常量。令我困惑的是,如果将类的构造函数标记为constexpr而非consteval,Clang会正常接受该代码。
结论
Clang的行为是不正确的,这属于其实现缺陷:
- 根据C++标准,
static constexpr变量属于静态存储期的常量对象,其地址在编译期是确定的,可作为常量表达式的一部分。 consteval构造函数是立即求值的语境,此时this指向正在初始化的static constexpr对象,将this赋值给成员变量p_完全符合常量表达式的要求。- Clang在构造函数为
constexpr时接受代码,却在consteval时拒绝,这一行为存在明显不一致,进一步说明这是实现层面的Bug。
内容的提问来源于stack exchange,提问作者Andrea Agostini
相关产品推荐
相关产品推荐

