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

Với loại phần tử là const int, câu lệnh gán không được gán cho const int&? Điều này không biên dịch với LLVM 3.0. Tại sao VC++ cho phép nó?Tại sao VC++ 2010 cho phép biên dịch?

+2

Bạn dường như không hiểu từ "không xác định" trong "hành vi không xác định". – 6502

+0

flattery sẽ giúp bạn ở khắp mọi nơi - tôi có thể nói rằng tốt hơn một chút. – Tabber33

+1

Xin lỗi tôi không có ý xúc phạm, nhưng hành vi khá thường xuyên không xác định là nhầm lẫn với một sự cố thời gian chạy hoặc một lỗi bảo đảm biên dịch. Không gì có thể hơn sự thật. C++ có đầy đủ các vị trí trong đó một cái gì đó có vẻ hợp lý thực sự bị cấm nhưng trong đó trình biên dịch không chịu trách nhiệm kiểm tra. Hành vi không xác định nghĩa là không làm điều đó ... có nghĩa là các trình biên dịch biên dịch được tự do giả sử một lập trình viên sẽ không làm điều đó. Điều tồi tệ nhất có thể xảy ra thực sự chỉ là "không có gì" ... hoặc để nói nó không tốt hơn cho đến bản demo hoặc ngày triển khai. – 6502

Trả lời

8

Trong khi đó là hành vi không xác định và về cơ bản bất kỳ điều gì có thể xảy ra bao gồm những gì bạn đang thấy, tôi đã theo dõi điều này. Cụ thể là phân bổ tiêu chuẩn được định nghĩa trong thư viện VS2010 không phù hợp với tiêu chuẩn.

Tiêu chuẩn quy định rằng std::vector<T,Allocator>::value_type là typedef là Allocator::value_type. Giờ đây, trình phân bổ mặc định (nếu không được cung cấp) là std::allocator<T>value_type, theo Bảng 28 phải là Giống hệt T. Bây giờ việc thực hiện phân bổ tiêu chuẩn trong VS2010 giảm vòng loại const từ đối số loại, vì vậy std::allocator<const T>::value_typeT và không phải là const T. Điều quan trọng cần lưu ý là trình biên dịch không phải là không phù hợp để chấp nhận mã mà bạn đã cung cấp cho mỗi se, vì nó là Hành vi không xác định và trình biên dịch được tự do làm như nó thỏa mãn. Nhưng mặt khác, có một sự không phù hợp trong việc thực hiện std::allocator.

Bạn đã tự trả lời câu hỏi: Đó là Hành vi không xác định. Trình biên dịch không cần phải cung cấp một chẩn đoán, và kết quả của hoạt động có thể là bất cứ điều gì. Đó là trường hợp chất lượng thực hiện để phát hiện loại không thể gán và cung cấp thông báo lỗi có ý nghĩa (hoặc không)

+1

Tuy nhiên, người ta sẽ mong đợi * rằng trong bất kỳ triển khai thực tế nào của 'std :: vector', sẽ có một nơi nào đó cố gắng thực hiện một phép gán, điều này sẽ dẫn đến lỗi trình biên dịch phẳng. Thực tế là điều này không xảy ra làm cho nó thú vị; những gì thủ thuật là việc thực hiện MSVC kéo? –

+0

Bạn không muốn biết lỗi nào xẩy ra. –

+0

@MrLister: Quá muộn, tôi đã đốt cháy đôi mắt của mình trên cái đó ... –

Các vấn đề liên quan