2012-04-05 81 views
5
std::vector<const int> vci; 
vci.push_back(1); 
vci[0] = 2; 

對於元素類型是const int,賦值語句不應該分配給const int&?這不會與LLVM 3.0一起編譯。爲什麼VC++允許它?爲什麼VC++ 2010允許它編譯?

+2

您顯然不明白「未定義的行爲」中的「未定義」字是什麼意思。 – 6502 2012-04-05 19:30:47

+0

奉承會讓你無處不在 - 我可以說這更好一點。 – Tabber33 2012-04-05 19:41:08

+1

對不起,我並不是故意冒犯,但通常未定義的行爲被誤認爲是運行時崩潰或編譯錯誤保證。沒有什麼比真相更遙遠。 C++充滿了一些看似合理的東西確實被禁止的地方,但編譯器並不負責檢查。未定義的行爲意味着不要這麼做......意味着編譯器編寫者可以自由地假定程序員不會那樣做。可能發生的最糟糕的事情實際上只是「沒有」......或者直到演示或部署日才說得更好。 – 6502 2012-04-05 19:56:25

回答

8

雖然它是未定義的行爲,基本上什麼可以發生,包括你所看到的,我已經跟蹤到這似乎是與圖書館與標準不兼容。特別是VS2010庫中定義的標準分配器不符合標準。

標準規定std::vector<T,Allocator>::value_typeAllocator::value_type的類型定義。現在默認分配器(如果沒有提供)是std::allocator<T>,其中value_type,根據表28必須是與T相同。現在,VS2010中的標準分配器的實現將const限定符從類型自變量中刪除,因此std::allocator<const T>::value_typeT,而不是const T

重要的是要注意,由於它是未定義的行爲並且編譯器可以隨心所欲地執行,因此編譯器並不接受您提供的代碼,因爲它是不符合要求的。但另一方面,在std::allocator實現中存在不符合。

您已經自行回答了問題:它是 未定義的行爲。編譯器不需要提供診斷,操作的結果可以是任何東西。這是檢測類型不可分配並提供有意義的錯誤消息的實施質量的情況(或不是)

+1

但是,我們可以期望*在任何實際的'std :: vector'實現中,都會有一個地方試圖做一個任務,這會導致一個平坦的編譯器錯誤。事實並非如此,這很有趣。 MSVC實施拉動的是什麼技巧? – 2012-04-05 19:32:54

+0

你不想知道g ++吐出了什麼錯誤。 – 2012-04-05 19:34:51

+0

@MrLister:太遲了,我已經燒焦了我的眼睛...... – 2012-04-05 19:35:11

相關問題