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

时间:2017-08-08 21:00:15

标签: c++ c++11 constexpr

考虑this code

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

为什么只有当我mark constructors constexpr时,编译器才能在不使用此关键字的情况下执行我期望的操作?请注意,优化启用编译器窗台doesn't generate the same resultcode that uses constexpr一样。

1 个答案:

答案 0 :(得分:1)

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

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

因此,要获得以前不可能的新行为,需要将原始代码更改为以前不合法的C ++。要求新的constexpr关键字在构造函数(或其他函数)声明上是一种简单有效的方法。

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