为什么我可以使用赋值运算符越界但不能使用 {}

Why can I go out of bounds with the assignment opeator but not with the {}

我的问题非常直截了当:为什么我可以将超出范围的值分配给这样的数组,而不是使用 {} 运算符:

int arr[2];

arr[2] = 2;

for(int num{0}; num < 3; num++)
    cout << arr[num] << endl;

但是当我这样做时,我从一开始就收到错误消息:

int arr[2] {1,2,3};

现在我知道分配一个超出数组范围的值可能会导致未定义的行为,因为这个问题已经向我澄清:

Accessing an array out of bounds gives no error, why?

但是为什么在第二种情况下我不能超出数组的限制呢?尽管这是错误的 - 而且我不打算这样做 - 我想知道这些情况下的区别。

两种情况完全不同。第一个是数组元素赋值。二是数组初始化。规则规定,如果您提供数组可以容纳的更多初始值设定项,则会出错。规则还规定,数组末尾后面的元素访问不是错误,而是未定义的行为。在其他语言中,在运行时对数组访问进行绑定检查,但在 C++ 中没有。所以它表现如此的原因是 C++ 标准委员会决定如此。

您当然可以问为什么 C++ 标准委员会如此决定。我认为答案是,C++ 试图尽可能地向后兼容,并且数组元素访问的规则一直都是这样。

也可以在编译时评估和检查初始化,而元素访问发生在运行时,编译器无法预见数组末尾后面是否确实存在访问。