2015-04-01 16 views
10

Nếu chương trình C++ áp dụng toán tử bitwise-not (~) cho giá trị boolean, điều đó có gọi hành vi không xác định không?Không sử dụng toán tử bitwise không (~) trên các giá trị boolean gọi hành vi không xác định?

Ví dụ: chương trình sau được xác định rõ là gì?

bool f = false; 
bool f2 = ~f; // is f2 guaranteed to be true, or is this UB? 
bool t = true; 
bool t2 = ~t; // is t2 guaranteed to be false, or is this UB? 

(Vâng, tôi biết có một nhà điều hành đó là tốt hơn phù hợp với các loại điều này;! Cho các mục đích của câu hỏi này, chúng ta sẽ bỏ qua sự tồn tại của nó;))

+3

Tôi đoán '~' kích hoạt đối số thành 'int' trước khi làm bất cứ điều gì, vì vậy ~ 0 sẽ chuyển thành' true'. Không thể chắc chắn 100% mà không cần tìm kiếm. – chris

+0

@chris, bạn nói đúng. –

+0

là UB để làm 'bool b = 13;' [hay cái gì đó tương tự]? –

Trả lời

8

5.3.1/10 Các toán hạng của ~ có trách nhiệm không thể thiếu hoặc unscoped kiểu enumeration; kết quả là sự bổ sung của toán tử. Chương trình khuyến mãi tích phân được thực hiện. [nhấn mạnh mỏ]

4.5/6 Giá trị loại bool có thể được chuyển đổi thành giá trị theo loại int, với false trở thành số không và true trở thành một.

4.5/7 Các chuyển đổi này được gọi là chương trình khuyến mãi không thể tách rời.

Vì vậy ~false là một int với một mẫu bit bao gồm tất cả những người thân - (. Theo yêu cầu của 3.9.1/7) của một người bổ sung của một mẫu bit đại diện cho 0, cụ thể là tất cả các số không Tương tự, ~true là một int đó là bổ sung của một đại diện bit của 1 - cụ thể là, tất cả những người có bit số ít quan trọng nhất. Cả hai giá trị này sẽ đánh giá thành true trong ngữ cảnh boolean.

+0

@MattMcNabb Tiêu chuẩn này nói ở đâu? Tôi đã thực sự tìm kiếm từ ngữ đó, và buồn bã thất bại. Có từ ngữ cho hiệu ứng này trong C99 ** 6.2.6.2 ** - có lẽ nó có thể được lập luận rằng từ ngữ này được đưa vào tiêu chuẩn C++ bằng cách tham chiếu, nhưng âm thanh đó giống như một đối số khá yếu. Tôi có thiếu một cái gì đó hiển nhiên? –

+0

@MattMcNabb Ah, phải. "Hệ thống số nhị phân thuần túy" là thuật ngữ nghệ thuật mà tôi đã quên. Hãy để tôi cập nhật câu trả lời. –

+1

Tôi đoán có một chút không gian để tranh luận rằng âm zero có thể là đại diện thay thế của '0', trong bổ sung của một số –

1
bool t = true; 
bool t2 = ~t; // is t2 guaranteed to be false, or is this UB? 

Tôi cho rằng nó không được đảm bảo, nhìn thấy như thế nào

bool b = true; 
    bool b1 = ~b; 
    cout << b1; 

kết quả đầu ra một "true"

tôi cho rằng nó đã làm với boo đại diện nạc ... nếu nó là một byte, sau đó 00000001 sẽ phủ nhận là 11111110 không phải là 0. Quảng cáo cũng có thể đang được phát, nhưng đó là giai điệu tương tự.

Chìa khóa ở đây là "bitwise" không "hợp lý". Vì vậy, người ta không nên mong đợi hai để phù hợp, trừ khi đại diện boolean là một chút.

Hành vi được xác định hoàn toàn dễ dàng.

3

Toán tử số học thực hiện các quảng cáo tích phân trên toán hạng của chúng. Cụ thể [expr.unary.op]/9 nói rằng điều này cũng xảy ra cho ~.

Vì vậy, ~t giống với ~1. Điều này cho một số nguyên khác không hợp lệ.

chuyển đổi Integer-to-bool được định nghĩa bởi [conv.bool]:

Một giá trị bằng không, giá trị con trỏ null, hoặc null giá trị con trỏ thành viên được chuyển đổi sang false; bất kỳ giá trị nào khác được chuyển thành true

do đó bool t2 = ~t; sản lượng t2 == true. Không có hành vi không xác định.


~f cũng giống như ~0. Trong phần bổ sung của 2, ~0 cung cấp cho -1, vì vậy chúng tôi sẽ có f2 == true.

Trong phần bổ sung 1 - nếu có hệ thống C++ sử dụng phần bổ sung 1 - thì hiệu quả của ~0 không rõ ràng.

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