2011-12-20 24 views
7

Vì chuyển đổi tiêu chuẩn C++ 0x thành g ++, tôi bắt đầu thấy lỗi 'thu hẹp chuyển đổi', đặc biệt khi chuyển từ 'int' sang ' ngắn 'mặc dù tôi hiểu lỗi bao gồm một swath rộng hơn nhiều của conversions.Hậu quả của việc bỏ qua việc thu hẹp chuyển đổi trong C++ 0x

Có ai có thể làm sáng tỏ một số lý do để giới thiệu mức độ an toàn bổ sung này không ?, Các hậu quả có thể có của việc vô hiệu hóa lỗi này là gì? (ngoài khả năng mất chính xác).

Cảm ơn.

+35

[Tên lửa của bạn có thể phát nổ] (http://www.ima.umn.edu/~arnold/disasters/ariane.html) –

+0

Nếu tôi từng làm việc trên một tên lửa, tôi chắc chắn sẽ ghi nhớ điều đó ;) –

+3

Đây là cái gì đó đã sản xuất _warnings_ luôn luôn, mãi mãi, và mãi mãi và một ngày, và đó là một điều tốt. Bây giờ nó là một _error_, nó gây tranh cãi cho dù đó là một điều tốt kể từ khi nó phá vỡ biên dịch hiện có, có lẽ là chính xác, mã. Tuy nhiên, nó ngăn cản một số không thể theo dõi lỗi, vì vậy tôi có thể thấy lý do. Tôi sẽ không vô hiệu hóa một logic lỗi như vậy, bởi vì khi bạn tình cờ vứt bỏ nửa trên của một giá trị và chúng có ý nghĩa, mã của bạn vẫn hoạt động tốt cho đến khi nó không, và sau đó bạn không biết tại sao. – Damon

Trả lời

11

Từ Chuyển nhượng và hợp chất toán tử gán [expr.ass]

Các nghĩa của x = {v}, trong đó T là kiểu vô hướng của biểu thức x, là của x = T (v) ngoại trừ không cho phép thu hẹp chuyển đổi (8.5.4).

và từ List-khởi [dcl.ini.list]

Nếu chuyển đổi hẹp (xem dưới đây) là bắt buộc để chuyển đổi bất kỳ đối số, chương trình là ill- hình thành.

Vì vậy, về cơ bản bạn không thể bỏ qua nó, chương trình của bạn không đúng định dạng khi có sự thu hẹp chuyển đổi.

Từ tuân thủ thực hiện:

Triển khai được yêu cầu để chẩn đoán các chương trình mà sử dụng phần mở rộng như vậy mà vô hình thành theo tiêu chuẩn quốc tế này. Tuy nhiên, đã làm như vậy, họ có thể biên dịch và thực hiện các chương trình như vậy.

Bjarne Stroustroup nói this:

Ngăn chặn thu hẹp

Vấn đề: C và C++ ngầm truncates:

 int x = 7.3;  // Ouch! 
    void f(int); 
    f(7.3);   // Ouch!

Tuy nhiên , Trong C++ 0x, {} khởi không hẹp:

int x0 {7.3}; // error: narrowing 
int x1 = {7.3}; // error: narrowing 
double d = 7; 
int x2{d};  // error: narrowing (double to int) 
char x3{7};  // ok: even though 7 is an int, this is not narrowing 
vector<int> vi = { 1, 2.3, 4, 5.6 }; // error: double to int narrowing 

Cách C++ 0x tránh được rất nhiều sự không tương thích là bằng cách dựa vào những giá trị thực tế của initializers (chẳng hạn như 7 trong ví dụ trên) khi có thể (và không chỉ nhập) khi quyết định chuyển đổi thu hẹp là gì. Nếu giá trị có thể được biểu diễn chính xác như loại mục tiêu, thì chuyển đổi sẽ không thu hẹp.

char c1{7};  // OK: 7 is an int, but it fits in a char 
char c2{77777}; // error: narrowing 

Lưu ý rằng dấu chấm động để nguyên chuyển đổi luôn coi hẹp - thậm chí 7.0 lên 7.

Vì vậy, trong một cách, thu hẹp cũng làm tăng loại an toàn.

+0

Câu trả lời tuyệt vời, chi tiết. Cảm ơn rất nhiều. –

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