2011-12-05 33 views
10

Ví dụ:Có phải -1u hợp lệ C++ không?

size_t x = -1u; 

if (x == -1u) 
    ... 

hợp lệ?

Nếu điều này hợp lệ, nó sẽ ngăn cảnh báo. tất nhiên trên hệ thống 32 bit x phải là 0xffffffff và trên hệ thống 64 bit , nó phải là 0xffffffffffffffff.

-Jochen

+7

Chữ thường không âm. Điều này được phân tách thành '- (1u)'. –

+0

@KerrekSB có tạo nên sự khác biệt ở đây không? –

+0

Vâng, nó làm cho kết quả đã được ký, vì vậy nó đánh bại mục đích của U. – StilesCrisis

Trả lời

6

1u có loại unsigned int. Điều này sau đó được phủ nhận bằng toán tử - đơn nhất. Hành vi này là như sau:

những tiêu cực của một số lượng unsigned được tính bằng cách trừ đi giá trị của nó từ 2 n, trong đó n là số bit trong toán hạng bạt (C++ 11 5.3.1/số 8).

-1u do đó được đảm bảo cung cấp cho bạn giá trị lớn nhất có thể đại diện bởi unsigned int.

Để nhận được giá trị lớn nhất thể hiện bằng loại không dấu tùy ý, bạn có thể truyền -1 cho loại đó. Ví dụ: đối với std::size_t, hãy xem xét static_cast<std::size_t>(-1).

0

Trong khi đây là kỹ thuật mã hợp lệ, bạn đang tùy thuộc vào hành vi phụ thuộc triển khai thực hiện: xử lý tràn của chuyển đổi một số tiêu cực đến unsigned. Tuy nhiên, nếu bạn cần so sánh có ý nghĩa với size_t với -1 vì các cuộc gọi API bạn đang sử dụng yêu cầu nó, hệ thống đã bị hỏng nhưng mã của bạn có khả năng hoạt động vì chúng sẽ phải làm điều tương tự ở phía bên kia của API.

+0

Tôi không phải là một chuyên gia C++ nhưng tôi nghi ngờ chuyển đổi từ kiểu số nguyên đã ký thành kiểu số nguyên không dấu được thực hiện xác định trong C++, bởi vì nó được định nghĩa trong C99. –

+0

Nó cũng được xác định. Tôi nghĩ rằng nó giống như 'x% 2^32' cho 32 bit. – Pubby

+1

Không có số âm nào được chuyển thành unsigned. '1u' là một số dương của kiểu' unsigned int', và số dương đó được phủ nhận bằng toán tử '-' đơn nhất. –

5

Tôi đã luôn luôn sử dụng ~ 0U cho mục đích "chưa ký, tất cả bit trên".

+4

... không hoạt động với kích thước 64 bit '. –

+1

SIZE_MAX có lẽ tốt hơn trong trường hợp đó, hoặc ~ 0ULL là dự phòng. – StilesCrisis

+0

Tuy nhiên hãy cẩn thận không viết '~ 0'. Cái 'U' ở đây rất quan trọng. Để thảo luận thêm, hãy xem http://stackoverflow.com/questions/809227/is-it-safe-to-use-1-to-set-all-bits-to-true –

1

Hành vi phụ thuộc triển khai trình biên dịch gây phiền toái. Bạn sẽ có thể làm được điều này, mặc dù:

size_t x = 0; 
x--; 

if ((x+1) == 0) 
+0

Đây là hành vi không xác định. Mã anh ấy đăng không phải. – Pubby

+0

@Pubby: Điều gì trong câu trả lời này bạn nghĩ rằng cuộc triển lãm hành vi không xác định? –

+1

Pubby bạn thấy UB ở đâu? Các loại chưa được ký (và size_t là một kiểu không dấu) có hành vi được xác định rõ ràng trên tràn, chúng quấn quanh. (Đã đăng ký tràn là UB). – AProgrammer

0

này rất có thể những gì bạn muốn:

size_t x = -1ull; 

if (x == -((size_t)-1ull)) 
    ... 

x sẽ được thiết lập để các số nguyên lớn nhất có thể, trong đó có thể không phải tất cả các bit được thiết lập. Sử dụng ~ 0 cho điều đó.

+0

Nhiều năm kể từ bây giờ khi 'size_t' rộng hơn' unsigned long long', 'size_t x = -1ull;' (có lẽ 'size_t' là typedef thành' uintmax_t' rộng) sẽ không được khởi tạo 'x' với giá trị tối đa. 'size_t x = SIZE_MAX;' sẽ vẫn hoạt động. – chux

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