2016-05-18 63 views
12

爲什麼我在嘗試創建負尺寸數組時遇到錯誤?負尺寸陣列無錯誤

#include <array> 

int main() 
{ 
    std::array<int, -1> arr; 
} 

-D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC我沒有得到任何錯誤。這是預期的行爲?

+2

哪個編譯器使用的是?我使用了gcc 5.3.1,並且我得到了錯誤'變量的大小'arr'太大' –

回答

8

std::array類型是:

template< 
    class T, 
    std::size_t N 
> struct array; 

當初始化第二個模板參數與-1,它被隱式轉換爲非常大的值作爲std::size_tunsigned(其是用C非法++由other answer和它作爲指出應該被診斷)。

另一種可能性是您的arr已經過優化。您可以通過將-fdump-tree-optimized標誌添加到gcc命令行來確認此情況。

如果你確保arr不優化掉了,我希望你應該得到的following warning

prog.cpp:5:25: error: size of variable 'arr' is too large 
    std::array<int, -1> arr; 
+1

這樣的警告檢查後不會發生優化嗎? – BartoszKP

+1

@BartoszKP我使用了'gcc --std = C++ 11 -O2 -fdump-tree-optimized arr_que.cpp',並確認代碼被優化爲只返回0;'正如你所期望的那樣。我不確定是否必須診斷模板參數誤用。 –

19

不,這不是合法的。 std::array的規範沒有明確規定這一點,但由於縮小了轉換次數,這是非法的。

§14.3.2/ 5:

對於整型或枚舉類型的非類型模板參數,轉換在轉換的常量表達式(5.19)允許 被應用。

§5.19/ 3:

A轉換的類型T的常量表達式是一個常量表達式, 隱式轉換爲類型T,其中,所述隱式轉換(如果有的話)是 在允許的文字常量表達式和隱式轉換序列 僅包含用戶定義的轉換,左值到右值轉換(4.1), 積分升級(4.5)和積分轉換(4.7),而不是縮小 轉換(8.5.4)

讓GCC抱怨的唯一方法是啓用-Wsign-conversion。這是一個known bug,他們沒有做任何動作來解決它。

在鐺你得到預期的錯誤消息:

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; 
+1

歷史註釋:在已發佈的C++ 11中,它是由實現定義的,不管這是否是一個縮小的轉換,但是DR 1449修復了這個問題,以便始終縮小 –