2015-09-30 17 views
7

C sau ++ biên dịch không có lỗi:Tại sao char không được ký hoặc unsigned, nhưng wchar_t là? chương trình

void f(char){} 
void f(signed char){} 
void f(unsigned char){} 
int main(){} 

Phiên bản wchar_t của cùng một chương trình không:

void f(wchar_t){} 
void f(signed wchar_t){} 
void f(unsigned wchar_t){} 
int main(){} 

lỗi: định nghĩa lại 'void f (wchar_t)'
void f (đã ký wchar_t) {}

Có vẻ như wchar_tunsigned.
Tại sao có sự không nhất quán trong quá tải?

+1

Điều này có vẻ không hợp pháp đối với tôi. Có phải C++? –

+0

@ArlieStephens Vâng, hãy xóa thẻ C tốt hơn. C++ mà không cần bất kỳ tiêu đề nào. –

+0

@ John3136 C++. Được xây dựng trong loại –

Trả lời

9

Các char s là tất cả các loại khác nhau và có thể bị quá tải

[basic.fundamental]/1

[...] Plain char , signed char , and unsigned char are three distinct types, collectively called narrow character types. [...]

wchar_t cũng là một loại riêng biệt, nhưng nó không thể đủ điều kiện với signed hoặc unsigned, chỉ có thể được sử dụng với các loại số nguyên chuẩn.

[dcl.type]/2

As a general rule, at most one type-specifier is allowed in the complete decl-specifier-seq of a declaration or in a type-specifier-seq or trailing-type-specifier-seq. The only exceptions to this rule are the following:

[...]

signed or unsigned can be combined with char , long , short , or int .

[dcl.type.simple]/2

[...] Table 9 summarizes the valid combinations of simple-type-specifiers and the types they specify.

enter image description here

Các signedness của wchar_t được thực hiện định nghĩa:

[basic.fundamental]/5

[...] Type wchar_t shall have the same size, signedness, and alignment requirements (3.11) as one of the other integral types, called its underlying type.

+0

Tôi tự hỏi tại sao trình biên dịch của tôi cho phép tôi thoát khỏi "unsigned wchar_t" nếu nó không phải là một vòng loại hợp lệ. Tôi chắc chắn sẽ không thể làm một cái gì đó như "bool unsigned" ... –

+2

@TrevorHickey Gửi báo cáo lỗi :) – user657267

4

char là loại riêng biệt từ cả hai signed charunsigned char. wchar_t là một loại khác biệt (cho mục đích nhận dạng loại), nhưng có cùng thuộc tính giống nhau (kích thước, ký kết và căn chỉnh) như một số loại tích phân khác.

Từ ISO 14882: 2003, 3.9.1:

Plain char , signed char , and unsigned char are three distinct types.

(...)

Type wchar_t is a distinct type whose values can represent distinct codes for all members of the largest extended character set specified among the supported locales (22.1.1). Type wchar_t shall have the same size, signedness, and alignment requirements (3.9) as one of the other integral types, called its underlying type.

Không có những điều như signed wchar_t hoặc unsigned wchar_t. Nó không được đề cập ở bất cứ đâu trong tài liệu.

4

char là loại cơ bản. wchar_t phát triển như đầu tiên một giải pháp thư viện (C), và sau đó trở thành một xây dựng trong loại với một loại tiềm ẩn, tương ứng với loại mà trước đó đã được sử dụng để typedef nó:

C++ 11 $ 3.9.1/5

Type wchar_t shall have the same size, signedness, and alignment requirements (3.11) as one of the other integral types, called its underlying type.

Điều này giải thích tại sao bạn không thể thay đổi signedness của wchar_t, nhưng nó không giải thích lý do tại sao có một loại char với signedness không xác định.


Ngoài ra, lựa chọn hầu hết các trình biên dịch mặc định là không thực tế vì nhiều lý do. Một lý do là các giá trị âm là gây phiền nhiễu và thường phải được đúc thành unsigned để so sánh chúng. Một lý do khác là các hàm phân loại ký tự C yêu cầu các giá trị không âm (trừ khi được thông qua EOF). Lý do thứ ba là trên máy cũ và dấu hiệu cũ hoặc máy bổ sung của một người có một giá trị không sử dụng được.

Có thể có một số giải thích về điều đó trong Stroustrup “ Thiết kế và tiến hóa của C++ ”, nhưng tôi nghi ngờ điều đó.

Nghe có vẻ như lịch sử cố định, một điều gì đó mà tại một thời điểm đã tạo ra một số ý thức, đối với công nghệ vào thời điểm đó.

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