2012-04-05 85 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

相关问题