2015-05-19 16 views
6

An unsigned int chỉ có thể chứa 32 bit dữ liệu. Tại sao trình biên dịch không đưa ra lỗi khi gán một giá trị lớn hơn cho nó so với những gì nó có thể giữ?Tại sao int không dấu này giữ nhiều dữ liệu hơn so với bộ nhớ có?

Tôi đã thử các giá trị khác và nó vẫn không có lỗi.

int main() 
{ 
    unsigned int mem = 0x89678456543454345934; 
    cout << mem; 

    return 0; 
} 
+2

Do hoạt động của tràn số nguyên không dấu được xác định rõ. Hay bạn đang hỏi tại sao đó là, tại sao, tại sao các nhà thiết kế của C++ lại không mắc lỗi này? – juanchopanza

+4

FWIW có thể bạn nên tăng mức độ cảnh báo của mình. –

+0

có lý do tại sao là – wazeeer

Trả lời

12

Đó là vì 0x89678456543454345934 lớn hơn std::numeric_limits<unsigned_int>::max(). Tuy nhiên, unsigned loại bọc xung quanh giá trị tối đa của chúng, vì vậy nếu phía bên tay phải có thể biểu thị bằng loại số nguyên bạn có hành vi được xác định rõ. Trong trường hợp đó, kết quả là 0x89678456543454345934 mod std::numeric_limits<unsigned_int>::max.

EDIT

Phía tay phải của nhiệm vụ của bạn là một integer literal. Để đại diện cho nó, trình biên dịch sử dụng kiểu đầu tiên (đặt hàng wrt kích thước của nó), trong đó các chữ số nguyên có thể phù hợp. Nếu không có loại như vậy, thì chương trình bị lỗi hình thức. Giá trị thập phân của hằng số của bạn là:

648873758694578209446196L 

Trên máy tính của tôi, cho cả hai kêu vang ++ và g ++ std::numeric_limits<unsigned long long>::max()18446744073709551615, đó là nhỏ hơn so với thường xuyên của bạn. Dường như chương trình của bạn sau đó được hình thành không đúng, trừ khi trình biên dịch sử dụng nhiều hơn 64 bit để đại diện cho unsigned long long, điều mà tôi rất nghi ngờ. Như @juanchopanza nhận xét, kêu vang ++ từ chối để biên dịch mã, với lỗi

error: integer constant is larger than the largest unsigned integer type

g ++ tuy nhiên đi trước và biên dịch nó, phát ra chỉ là một cảnh báo

warning: large integer implicitly truncated to unsigned type

Cảnh báo là khá khó hiểu, vì nó đề cập sang phía bên tay phải, không để việc chuyển đổi hơn nữa để unsigned int, mà bạn nhận được

warning: large integer implicitly truncated to unsigned type [-Woverflow]

Trên máy tính của tôi std::numeric_limits<unsigned int>::max()4294967295 và do đó 648873758694578209446196L % 42949672953633002191L. Tuy nhiên khi tôi chạy chương trình của bạn, tôi nhận được 1412716852. Điều này xảy ra vì chương trình không đúng định dạng, và tiếc là trình biên dịch không phát ra lỗi (nó không được bắt buộc theo tiêu chuẩn) mà chỉ là cảnh báo.

+2

Clang cung cấp cho tôi một lỗi có liên quan hơn: 'error: integer literal quá lớn để được thể hiện bằng bất kỳ loại số nguyên nào ' – juanchopanza

+0

yup g ++ thay đổi giá trị của mem từ 9535901844731353396 thành 1412716852 –

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