为什么编译器无法弄清楚构造函数实际上是 constexpr?

Why compiler cannot figure out that constructors are in fact constexpr?

本文关键字:实际上 constexpr 构造函数 弄清楚 编译器 为什么      更新时间:2023-10-16

请考虑以下代码:

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;
}

为什么编译器不能弄清楚并避免生成所有混乱的代码来初始化这两个全局静态mx0mx1

为什么只有当我标记构造函数 constexpr 时,编译器才能在没有这个关键字的情况下做我希望它做的事情?请注意,启用优化后,编译器 sill 不会生成与使用 constexpr 的代码相同的结果。

首先,让我说这是一个猜测,但(我相信(这是一个受过教育的猜测。

我不是C++标准委员会的成员,但从我在网上阅读和看到的内容来看,我可以告诉你,他们在与该语言以前版本的向后兼容性方面非常热衷(现在仍然如此(。 如果允许C++11编译器静默地将constexpr应用于构造函数和常量变量的初始化,那么在C++11下重新编译时,这将改变现有程序的行为 - 从运行时到编译时初始化。 一般来说,简单地在语言的更高版本中重新编译时改变程序的行为被认为是一件坏事*。

因此,要获得以前无法实现的新行为,您需要将原始代码更改为以前不会合法C++的内容。 要求在构造函数(或其他函数(声明上使用 newconstexpr关键字是一种简单有效的方法。


*当然,每个规则都有例外,例如编译器生成的移动构造函数/赋值运算符,但他们非常小心,除非证明是良性的,否则这些不能自动添加。