为什么编译器无法弄清楚构造函数实际上是 constexpr?
Why compiler cannot figure out that constructors are in fact constexpr?
请考虑以下代码:
struct matrix
{
matrix(int a, int b, int c, int d)
: a(a), b(b), c(c), d(d){}
matrix()
: a(0), b(0), c(0), d(0){}
int a, b, c, d;
};
static const matrix mx0;
static const matrix mx1(1,1,1,1);
const matrix& test(bool f)
{
return f ? mx1 : mx0;
}
为什么编译器不能弄清楚并避免生成所有混乱的代码来初始化这两个全局静态mx0
和mx1
?
为什么只有当我标记构造函数 constexpr 时,编译器才能在没有这个关键字的情况下做我希望它做的事情?请注意,启用优化后,编译器 sill 不会生成与使用 constexpr 的代码相同的结果。
首先,让我说这是一个猜测,但(我相信(这是一个受过教育的猜测。
我不是C++标准委员会的成员,但从我在网上阅读和看到的内容来看,我可以告诉你,他们在与该语言以前版本的向后兼容性方面非常热衷(现在仍然如此(。 如果允许C++11编译器静默地将constexpr
应用于构造函数和常量变量的初始化,那么在C++11下重新编译时,这将改变现有程序的行为 - 从运行时到编译时初始化。 一般来说,简单地在语言的更高版本中重新编译时改变程序的行为被认为是一件坏事*。
因此,要获得以前无法实现的新行为,您需要将原始代码更改为以前不会合法C++的内容。 要求在构造函数(或其他函数(声明上使用 newconstexpr
关键字是一种简单有效的方法。
*当然,每个规则都有例外,例如编译器生成的移动构造函数/赋值运算符,但他们非常小心,除非证明是良性的,否则这些不能自动添加。
相关文章:
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 多成员Constexpr结构初始化
- 条件constexpr函数
- constexpr 函数中的非文字(通过 std::is_constant_evaluated)
- Visual C++ constexpr Hints
- 如何确认我的constexpr表达式实际上已经在编译时执行
- 为什么constexpr的性能比正常表达式差
- 是否可以使用if constexpr删除控制流语句
- 要与"if constexpr"一起使用的编译时消息(在预处理器之后)
- 为什么我的删除节点函数实际上没有删除节点?
- 为什么std::isnan 不是 constexpr?
- Constexpr替代了新的放置方式,可以让内存中的对象保持未初始化状态
- 当一个值是非常量但用常量表达式初始化时使用constexpr
- 更多constexpr容器是否需要mark_immutable_if_consexpr
- C++从其他 constexpr 创建 lambda 不能按顺序执行 Constexpr
- constexpr上下文中std::initializer_list的验证
- constexpr构造函数需要常量成员函数时出现问题
- vs 2015 constexpr变量不恒定,但与2019相比还好吗
- 为什么编译器无法弄清楚构造函数实际上是 constexpr?
- 什么时候 constexpr 实际上不是 constexpr