2010-08-14 14 views
23

Thông thường, C yêu cầu toán hạng toán tử nhị phân được thăng cấp thành loại toán hạng cao hơn. Điều này có thể được khai thác để tránh điền mã với dàn diễn viên tiết, ví dụ:Bitshift và quảng bá số nguyên?

if (x-48U<10) ... 
y = x+0ULL << 40; 

, vv

Tuy nhiên, tôi đã phát hiện ra rằng, ít nhất là với gcc, hành vi này không làm việc cho bitshifts. I E.

int x = 1; 
unsigned long long y = x << 32ULL; 

tôi mong chờ các loại của toán hạng bên phải để làm cho toán hạng bên trái để được thăng unsigned long long để sự thay đổi thành công. Nhưng thay vào đó, gcc in cảnh báo:

warning: left shift count >= width of type 

Gcc bị hỏng hoặc tiêu chuẩn có ngoại lệ với quy tắc quảng bá loại cho bithifts không?

+0

Quảng cáo có được quảng cáo không, bất kể cảnh báo? (nó chỉ là một cảnh báo, sau khi tất cả). –

+1

Bạn không thể sử dụng một macro ngắn để tạo ra đoạn dài dòng? Giống như '#define ULL (x) ((unsigned long long) x)'? – Borealid

+1

@Robert: Không, nó tạo ra no-op, như thể tôi đã viết đồng bằng '<< 32'. @Borealid: Vâng tôi có thể, nhưng tôi thích viết mã có thể được sao chép và dán bất kỳ nơi nào (ví dụ: các dự án khác) mà không yêu cầu thêm định nghĩa/tiêu đề. Tôi ghét những thứ như 'typedef unsigned int uint;'. –

Trả lời

23

Cái gọi là chuyển đổi số học thông thường áp dụng cho nhiều toán tử nhị phân, nhưng không áp dụng cho tất cả các toán tử nhị phân. Ví dụ: chúng không áp dụng cho toán tử dịch chuyển bit, & &, ||, toán tử dấu phẩy và toán tử gán. Đây là quy tắc cho các nhà khai thác chút thay đổi:

6.5.7 ... 3 Semantics ...
Các chương trình khuyến mãi số nguyên được thực hiện trên mỗi toán hạng. Loại kết quả là kết quả của toán hạng bên trái được quảng bá. Nếu giá trị của toán hạng bên phải là âm hoặc lớn hơn hoặc bằng với chiều rộng của toán hạng trái được thăng hạng, hành vi là không xác định.

+1

Cảm ơn bạn, đây là những gì tôi đang tìm kiếm. –

0

Sự cố thực sự là quảng cáo chỉ hoạt động theo bất kỳ nền tảng nào của bạn xác định là int. Như một số câu trả lời khác đã nêu, toán tử bit shift sẽ thúc đẩy toán hạng bên trái thành int. Tuy nhiên, tại đây, int được định nghĩa là giá trị 32 bit. Việc chuyển đổi số nguyên sẽ không được quảng cáo đến một số long long (64 bit).