Reputation: 11022
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.
#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).
Three compilers, three results. Is this undefined behavior or is this is a bug in Visual Studio?
Upvotes: 4
Views: 414
Reputation: 173014
GCC is correct, the behavior is defined by the standard.
$5.3.4/7 New [expr.new]
The expression in a noptr-new-declarator is erroneous if:
...
(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.
...
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).
Upvotes: 4