Visual Studio和Clang不会抛出std :: bad_array_new_length

时间:2021-11-17 12:38:43

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)匹配的类型的异常来终止。