This is a follow up to to a prior question.
这是对先前问题的跟进。
In the following program Visual Studio 2015 and Clang both do not throw std::bad_array_new_length
. gcc does.
在下面的程序中,Visual Studio 2015和Clang都不会抛出std :: bad_array_new_length。 gcc呢。
#include <iostream>
#include <random>
#include <exception>
#include <new>
int main()
{
std::random_device rd;
std::uniform_int_distribution<int> dist(2,2);
try {
auto arr = new int[dist(rd)][4][2]{{{1}},{{2}},{{3}}}; // may write to unallocated memory
auto val1 = arr[0][0][0];
auto val2 = arr[1][0][0];
auto val3 = arr[2][0][0];
auto result = val1 + val2 + val3;
std::cout << result;
}
catch (std::exception const& e) {
std::cerr << e.what() << '\n';
}
return 0;
}
In Visual Studio the program crashes without any message. In Clang there is no error (perhaps because it avoided the allocation as mentioned in this answer).
在Visual Studio中,程序崩溃,没有任何消息。在Clang中没有错误(也许是因为它避免了本回答中提到的分配)。
Three compilers, three results. Is this undefined behavior or is this is a bug in Visual Studio?
三个编译器,三个结果。这是未定义的行为还是这是Visual Studio中的错误?
1 个解决方案
#1
3
GCC is correct, the behavior is defined by the standard.
GCC是正确的,行为由标准定义。
$5.3.4/7 New [expr.new]
$ 5.3.4 / 7新[expr.new]
The expression in a noptr-new-declarator is erroneous if:
在以下情况下,noptr-new-declarator中的表达式是错误的:
...
...
(7.4) — the new-initializer is a braced-init-list and the number of array elements for which initializers are provided (including the terminating ’\0’ in a string literal (2.13.5)) exceeds the number of elements to initialize.
(7.4) - new-initializer是一个braced-init-list,为其提供初始值设定项的数组元素的数量(包括字符串文字(2.13.5)中的终止'\ 0')超过了要素的数量。初始化。
...
...
a new-expression with an erroneous expression does not call an allocation function and terminates by throwing an exception of a type that would match a handler (15.3) of type
std::bad_array_new_length
(18.6.2.2).具有错误表达式的new表达式不会调用分配函数,并通过抛出与std :: bad_array_new_length(18.6.2.2)类型的处理程序(15.3)匹配的类型的异常来终止。
#1
3
GCC is correct, the behavior is defined by the standard.
GCC是正确的,行为由标准定义。
$5.3.4/7 New [expr.new]
$ 5.3.4 / 7新[expr.new]
The expression in a noptr-new-declarator is erroneous if:
在以下情况下,noptr-new-declarator中的表达式是错误的:
...
...
(7.4) — the new-initializer is a braced-init-list and the number of array elements for which initializers are provided (including the terminating ’\0’ in a string literal (2.13.5)) exceeds the number of elements to initialize.
(7.4) - new-initializer是一个braced-init-list,为其提供初始值设定项的数组元素的数量(包括字符串文字(2.13.5)中的终止'\ 0')超过了要素的数量。初始化。
...
...
a new-expression with an erroneous expression does not call an allocation function and terminates by throwing an exception of a type that would match a handler (15.3) of type
std::bad_array_new_length
(18.6.2.2).具有错误表达式的new表达式不会调用分配函数,并通过抛出与std :: bad_array_new_length(18.6.2.2)类型的处理程序(15.3)匹配的类型的异常来终止。