2011-12-20 48 views
8

Tôi chắc chắn rằng mã sau không nên biên dịch. Nhưng, trong g ++, nó biên dịch! Xem nó biên dịch tại http://codepad.org/MR7Dsvlz.Là một diễn viên từ (con trỏ đến const) đến (con trỏ đến không-const) không hợp lệ C++?

Mã:

#include <iostream> 

using namespace std; 

int main() { 
    int x = 32 ; 
    // note: if x is, instead, a const int, the code still compiles, 
    // but the output is "32". 

    const int * ptr1 = & x ; 

    *((int *)ptr1) = 64 ; // questionable cast 
    cout << x ;   // result: "64" 
} 

là g ++ do lỗi của biên dịch này?

+0

Nếu bạn muốn bỏ đi constness (và bạn chắc chắn nó được cho phép) cách C++ thành ngữ để làm điều đó là với 'const_cast (ptr1)' - mặc dù C cast cũng sẽ hoạt động như bạn vừa thấy . –

+1

Điều này hữu ích khi đọc: http://stackoverflow.com/questions/357600/is-const-cast-safe – Pubby

Trả lời

9

số Theo §5.4.4 của chuẩn C++, các diễn viên có thể được thực hiện bởi một dàn diễn viên C-style là:

— a const_cast (5.2.11), 
— a static_cast (5.2.9), 
— a static_cast followed by a const_cast, 
— a reinterpret_cast (5.2.10), or 
— a reinterpret_cast followed by a const_cast 

này được biết đến rộng rãi như "đúc đi const -ness" và trình biên dịch sẽ không tuân thủ phần đó của tiêu chuẩn nếu nó không biên dịch mã đó.

Khi ildjarn chỉ ra, sửa đổi đối tượng const bằng cách truyền đi const ness là hành vi không xác định. Chương trình này không thể hiện hành vi không xác định bởi vì, mặc dù một đối tượng được trỏ đến bởi con trỏ tới số const, chính đối tượng đó không phải là const (nhờ R.Martinho và eharvest để sửa lỗi đọc xấu của tôi).

+0

"Không." - Vì vậy, g + + nên đã biên dịch mã? "trình biên dịch sẽ không tuân thủ phần đó của tiêu chuẩn nếu nó không biên dịch mã đó." - Vì vậy, g ++ là phù hợp với một phần của tiêu chuẩn? –

+0

@noshenim câu hỏi của bạn là "G ++ có bị lỗi khi biên dịch không?" mà tôi trả lời "Không". Vì vậy, g ++ nên, và làm, biên dịch mã, và nó phù hợp với phần đó của tiêu chuẩn. –

+3

Noshenim, bạn hỏi những câu hỏi mâu thuẫn. Bất kỳ câu trả lời * yes * nào cho câu hỏi tiêu đề của bạn là câu trả lời * không * cho câu hỏi về nội dung. Hãy cẩn thận hơn lần sau. –

3

Không. G ++ không phải là do lỗi khi biên dịch mã của bạn. các diễn viên bạn đã làm là hợp lệ.

(int *)ptr1 là một diễn viên c. tương đương trong C++ là const_cast<int*>(ptr1). phong cách thứ hai là rõ ràng hơn để đọc.

nhưng, cần phải thực hiện phép đúc này (để sửa đổi biến const) hiển thị sự cố trong thiết kế.

1

Dòng *((int *)ptr1) = 64 tương đương với *(const_cast<int*>(ptr1)) = 64const_cast là lần truyền đầu tiên được thực hiện khi bạn sử dụng ký pháp đúc.

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