2014-09-02 17 views
9

Để cung cấp cho một chút nền (không liên quan đến câu hỏi, mà sẽ làm theo), trong C++ 11 tôi nhận thấy một vấn đề thu hẹp:Quy tắc quảng cáo số nguyên không đổi?

int foo[] = { 0xFFFFFFFF }; 

này đã thất bại trong việc biên dịch (thu hẹp chuyển đổi) vì 0xFFFFFFFF là một unsigned int . Tuy nhiên, tôi đã thấy các trường hợp trong đó 0xFF được ký.

Tôi đã xem xét các quy tắc quảng cáo số nguyên, nhưng điều này chủ yếu nằm trong ngữ cảnh của các giá trị và không phải là rvalues ​​/ hằng số. Trình biên dịch xác định loại hằng số (không có hậu tố chữ) như thế nào? Có tài liệu hoặc một bảng nhỏ đẹp/"cheat sheet" cho thấy các quy tắc cho điều này? Tôi thậm chí không thực sự chắc chắn những gì này được gọi là, nếu không tôi đã cố gắng để tìm thấy nó bản thân mình trong tiêu chuẩn C++ 11.

Xin cảm ơn trước.

+1

Đây là loại hẹp nhất cần thiết với ký được ưu tiên và tối thiểu là 'int'. – chris

+0

Tôi đã thêm một số chi tiết bổ sung vào câu trả lời của tôi mà bạn có thể thấy hữu ích/thú vị. –

Trả lời

12

Có một bảng trong tiêu chuẩn, được sao chép trên cppreference.com: http://en.cppreference.com/w/cpp/language/integer_literal

Đặc biệt, một hex hoặc số nguyên bát phân đen không có hậu tố được coi là có các loại đầu tiên trong danh sách sau đây, trong đó nó giá trị có thể được biểu diễn:

int 
unsigned int 
long int 
unsigned long int 
long long int 
unsigned long long int 

0xFFFFFFFF là quá lớn cho int nếu int dài 32 bit, vì vậy unsigned int được chọn. Nhưng 0xFF phù hợp thoải mái với một số int, vì vậy, int.

+0

Vì vậy, nó an toàn để nói rằng nó nhìn vào phạm vi tách rời, và không cụ thể độ sâu bit của nó. Điều đó giúp làm cho mọi thứ trở nên rõ ràng, nếu có. –

+0

@RobertDailey Đúng vậy, vâng, nó không trực tiếp phụ thuộc vào số lượng bit, mặc dù rõ ràng là nó gián tiếp. – Brian

6

gì được gọi là gọi là Integer hằng trong C được gọi là literals số nguyên trong C++. Các quy tắc sử dụng để xác định loại của một nguyên đen được bảo hiểm trong draft C++ standard phần 2.14.2literals Integer bảng 6 mà nói:

Các loại một số nguyên nghĩa đen là người đầu tiên của danh sách tương ứng trong Bảng 6 trong đó giá trị của nó có thể được biểu diễn.

và cho Octal hoặc liên tục thập lục phân không có hậu tố bảng có trình tự sau:

int 
unsigned int 
long int 
unsigned long int 
long long int 
unsigned long long int 

Vì vậy 0xFF có thể được biểu diễn dưới dạng một int trong khi các loại đầu tiên có thể đại diện cho 0xFFFFFFFF sẽ là unsigned int.

Trình tự Decimal Constants là như sau:

int 
long int 
long long int 

Như chúng ta có thể thấy hexidecimal và bát phân literals hành xử khác nhau, và chúng ta có thể thấy that C99 has the same table. Các Rationale for International Standard—Programming Languages—C nói như sau về vấn đề này:

Không giống như hằng số thập phân, bát phân và hằng số thập lục phân quá lớn để được ints đang gõ như int unsigned nếu trong phạm vi của loại đó, kể từ nó có nhiều khả năng rằng họ đại diện cho chút mẫu hoặc mặt nạ, được thường được xử lý tốt nhất là số không dấu, thay vì "thực".

cppreference integer literal section cũng trích dẫn bảng 6 trong Các loại đen phần phụ.

+2

+1 để trích dẫn tiêu chuẩn và cũng cho tôi biết khái niệm này được đặt tên là gì. –

+0

về cơ bản, nếu bạn muốn sử dụng số nguyên đã ký, bạn chỉ nên sử dụng 'int foo [] = {-1}; ' – pqnet

2

0xFF không bao giờ là số âm. Đây là một cách khác để viết 255. (Nó có loại int).

0xFFFFFFFF là số dương lớn. Có một bảng dưới [lex.icon] chỉ định loại là một hằng số nguyên. Đối với các hằng số hex không có hậu tố, đây là loại đầu tiên trong danh sách sau có thể chứa số dương lớn đó: int, unsigned int, long int, unsigned long int, long long int, unsigned long long int. Việc triển khai có thể thêm các loại tùy chỉnh ot danh sách này.

+0

@TC Tôi có nghĩa là nó không bao giờ tiêu cực; sửa chữa –

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