2015-09-30 1 views
7

Le programme C++ suivant compile sans erreur:Pourquoi char n'est ni signé ni signé, mais wchar_t l'est?

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

La version wchar_t du même programme ne fait pas:

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

erreur: redéfinition du 'vide f (wchar_t)'
vide f (signé wchar_t) {}

Il semble que wchar_t soit unsigned.
Pourquoi y a-t-il une incohérence dans la surcharge?

+1

Cela ne me semble pas légal C. Est-ce C++? –

+0

@ArlieStephens Oui, mieux vaut supprimer le tag C. C++ sans aucun en-tête nécessaire. –

+0

@ John3136 C++. Construit en type –

Répondre

9

Les char s sont tous les types distincts et peuvent être surchargées

[basic.fundamental]/1

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

wchar_t est aussi un type distinct, mais il ne peut pas être qualifié avec signed ou unsigned, qui ne peut être utilisé qu'avec les types entiers standard.

[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

Le signedness de wchar_t est mise en oeuvre selon:

[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

Je me demande pourquoi mon compilateur me laisse sortir avec "unschargé wchar_t" si ce n'est pas un qualificateur valide. Je ne serais certainement pas capable de faire quelque chose comme "unsigned bool" ... –

+2

@TrevorHickey Déposer un rapport de bug :) – user657267

4

char est un type distinct à la fois signed char et unsigned char. wchar_t est encore un autre type distinct (pour l'identité de type), mais qui a exactement les mêmes propriétés (taille, signature et alignement) que n'importe quel autre type intégral.

de la norme 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.

Il n'y a pas une telle chose comme signed wchar_t ou unsigned wchar_t. Cela n'est mentionné nulle part dans le document.

4

char est un type fondamental. wchar_t évolué comme d'abord une solution de bibliothèque (en C), puis est devenu un type construit avec un type sous-jacent, correspondant au type qui a été utilisé précédemment pour typedef il:

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.

Cela explique pourquoi vous ne pouvez pas changer le signedness de wchar_t, mais il n'explique pas pourquoi il y a un type char avec signedness non précisée.


En outre, le choix de la signature char que la plupart des compilateurs défaut, est peu pratique pour plusieurs raisons. Une des raisons est que les valeurs négatives sont ennuyantes et doivent généralement être converties en non signées afin de les comparer. Une autre raison est que les fonctions de classification des caractères C nécessitent des valeurs non négatives (sauf si elles sont passées EOF). Une troisième raison est que sur les vieilles machines de magnitude et de signe ou de complément, il y a une valeur inutilisable.

Il peut y avoir une explication de cela dans “ de Stroustrup La conception et l'évolution de C++ ”, mais j'en doute.

Cela ressemble à historique gelé, quelque chose qui, à un moment donné, avait un sens, pour la technologie à l'époque.