"constexpr"变量"used in its own initializer":Clang与GCC
`constexpr` variable "used in its own initializer": Clang vs. GCC
这个问题似乎与现有问题有关,但我不理解答案中提供的"可移植的解决方法"(涉及const auto this_ = this;
),而且我认为下面的例子更容易理解。
我正在播放以下C++17代码片段(实时演示):
#include <iostream>
struct Test {
const char* name_{nullptr};
const Test* src_{nullptr};
constexpr Test(const char* name) noexcept
: name_{name}
{}
constexpr Test(const Test& src) noexcept
: src_{&src}
{
name_ = src_->name_;
src_ = nullptr;
}
};
template<char c>
void print_constexpr_char() {
std::cout << c << std::endl;
}
int main() {
constexpr const char* in = "x";
constexpr auto foo = Test{in};
constexpr auto bar = Test{foo};
std::cout << bar.name_ << std::endl;
print_constexpr_char<bar.name_[0]>();
return 0;
}
GCC 7.2编译失败,而Clang 5.0.0没有发现任何问题。GCC错误本质上读取
错误:"bar"的值在常量表达式中不可用
注意:"bar"在其自身的初始值设定项中使用
在意识到删除最终的print_constexpr_char
会使代码编译后,我更加困惑,尽管它仍然包含GCC经常抱怨的行constexpr auto bar = Test{foo};
("在其自己的初始化器中使用")。
- 这里哪个编译器是正确的
- 如何理解GCC注释(如果不是bug的话),即"在自己的初始值设定项中使用"是有害的,如果结果随后被用于常量表达式中
- 在将正在构建的对象转换为可以存储在
constexpr
变量中的最终状态之前,是否有一种有效的方法/解决方法可以使用constexpr
构造函数中的指针作为中间阶段
GCC拒绝代码是正确的(但是错误消息可能需要一些工作)。除非变量具有静态存储持续时间,否则不能在常量表达式中使用该变量的地址。
foo
不是静态的。如果你把它移到main
之外,一切都会好起来的。演示
下面标记的线是问题所在:
constexpr Test(const Test& src) noexcept
: src_{&src} <--- That
标准参考:(强调矿)
[expr.const]
常量表达式是指允许的实体的glvalue核心常量表达式常量表达式(定义如下)的结果,或值满足的prvalue核心常量表达式以下约束:
(5.2)--如果值为指针类型,则包含具有静态存储持续时间的对象的地址超过该对象末尾的地址(8.7)、函数的地址或空指针值,
相关文章:
- 奇怪的结构&GCC&clang(void*返回类型)
- 数据成员SFINAE的C++17测试:gcc vs clang
- 在clang++预处理器中确定gcc工具链版本
- 为什么lambda在clang上崩溃而不是在gcc上崩溃
- gcc和clang在表达式是否为常量求值的问题上存在分歧
- 如何使用Clang/GCC在Mac上为C/C++设置VSCode
- 一位朋友将模板函数缩写为clang和gcc
- 类模板参数推导-clang和gcc不同
- GCC和Clang在与__builtin_constant_p相关的static_assert方面有所不同
- 为什么 gcc 和 clang 为函数模板的实例化生成不同的符号名称?
- MSVC发现这种方法调用模棱两可,而Clang / GCC则不然吗?
- Clang&GCC以不同的方式诠释系列演员表
- MSVC:无法识别的模板声明/定义(使用 Clang/GCC 编译)
- 构造函数上的SFINAE在VC2017中工作,但在clang / gcc中不起作用
- clang/GCC编译器内在的无相应编译器标志
- Clang & GCC 误推模板参数
- Clang & GCC 在使用智能指针时不会警告非虚拟基析构函数的多态性?
- Clang/GCC插件,用于解释自定义的c++11属性
- sscanf中uint16_t的正确且可移植的(Clang/GCC)修饰符是什么
- 依赖模板可以在Visual Studio中编译,但在clang/gcc中失败