负尺寸数组没有错误

use*_*851 13 c++ arrays c++11 stdarray

为什么我在尝试创建负大小的数组时出错?

#include <array>

int main()
{
    std::array<int, -1> arr;
}
Run Code Online (Sandbox Code Playgroud)

随着-D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC我没有得到任何错误.这是预期的行为吗?

uh *_*per 20

不,这不合法.没有任何关于std::array明确阻止这种情况的规范,但由于缩小了转换次数,这是非法的.

§14.3.2/ 5:

对于整数或枚举类型的非类型模板参数,将应用转换常量表达式(5.19)中允许的转换.

§5.19/ 3:

T类型的转换常量表达式是一个文字常量表达式,隐式转换为类型T,其中隐式转换(如果有)在文字常量表达式中是允许的,而隐式转换序列仅包含用户定义的转换,lvalue-to-除缩小转化次数之外的右值转换(4.1),整数促销(4.5)和积分转换(4.7)(8.5.4)

让GCC抱怨的唯一方法是启用-Wsign-conversion.这是一个已知的错误,他们没有采取任何动作来修复它.

在Clang中,您会收到预期的错误消息:

error: non-type template argument evaluates to -1, which cannot be 
narrowed to type 'std::size_t' (aka 'unsigned long') [-Wc++11-narrowing]
    std::array<int, -1> arr;
Run Code Online (Sandbox Code Playgroud)


Moh*_*ain 8

类型std::array是:

template< 
    class T, 
    std::size_t N 
> struct array;
Run Code Online (Sandbox Code Playgroud)

当初始化第二个模板参数用-1,它是隐式转换为一个非常大的值std::size_tunsigned(这是用C++非法通过的指出对方的回答,它应诊断).

另一种可能性是你arr的优化了.您可以通过向-fdump-tree-optimizedgcc命令行添加标志来确认这一点.

如果你确保arr没有优化,我希望你得到以下警告:

prog.cpp:5:25: error: size of variable 'arr' is too large
     std::array<int, -1> arr;
Run Code Online (Sandbox Code Playgroud)