71 votes

Pourquoi le compilateur fait-il correspondre "char" à "int" mais pas à "short" ?

J'ai un petit programme :

#include<iostream>
using namespace std;

void f(int)   { cout << "int\n";   }
void f(short) { cout << "short\n"; }

int main(void){
    char c = 0;
    f(c);
    return 0;
}

Il imprime int . J'ai pensé que, si c'est à cause de la "promotion des nombres entiers", pourquoi n'est-ce pas le cas ? short préféré ?

Je sais aussi que la promotion des nombres entiers se fait dans une expression (comme A=B). Mais je n'ai pas d'expression dans l'appel à f(), n'est-ce pas ?

Si c'est lié à la règle de résolution des surcharges, pourquoi faire passer char à f aura pour conséquence que les compilateurs préféreront int a short ?

Si je supprime f(int) entonces f(c) appellera f(short) !

Donc, en résumé, ma question est la suivante : est-ce lié à la "promotion des nombres entiers" ou simplement à la "règle de résolution des surcharges" ? Et pourquoi ?

0 votes

Y a-t-il un problème que vous essayez de résoudre ou est-ce de la pure curiosité ?

4 votes

En (un peu douteux) La raison pour laquelle il n'y a pas de promotion courte est que int est considérée comme la taille optimale du processeur/registre, short juste une disposition de la mémoire emballée. Ainsi, un int ("registre") est utilisé pour traiter un char . On suppose qu'une soustraction de short ne serait pas plus efficace qu'une soustraction de int.

4 votes

@JoopEggen - ce n'est pas un raisonnement (douteux ou non), c'est une décision de conception : en C et C++, int est censé être la taille naturelle de l'architecture, c'est donc ce qu'il faut utiliser lorsqu'il n'y a pas de bonne raison de préférer autre chose.

67voto

user2079303 Points 4916

La promotion (intégrale) est préférée à d'autres conversions (intégrales) par résolution des surcharges

Classement des séquences de conversion implicites

1) Correspondance exacte : aucune conversion requise, conversion de lvalue à rvalue, conversion de qualification, conversion de pointeur de fonction, (depuis C++17) conversion définie par l'utilisateur du type de classe vers la même classe.

2) Promotion : promotion intégrale, promotion en virgule flottante

3) Conversion : conversion intégrale, conversion en virgule flottante, conversion en virgule flottante-intégrale, conversion de pointeur, conversion de pointeur à membre, conversion booléenne, conversion définie par l'utilisateur d'une classe dérivée à sa base

Donc, la promotion de char a int est préféré à la conversion de char a short .


Qu'est-ce que la promotion ? vous pouvez vous demander. Il s'agit d'un type particulier de conversion décrit par la norme.

Pourquoi est-ce que char a short pas une promotion ? vous pouvez continuer. Promotion intégrale est toujours de int ou un caractère plus grand. Il n'y a pas de promotions pour short .

Les conversions implicites suivantes sont classées comme des promotions intégrales :

  • signed char ou signed short peuvent être convertis en int ;

  • unsigned char ou unsigned short peut être converti en int s'il peut contenir toute sa plage de valeurs, et en unsigned int sinon ;

  • char peut être converti en int ou unsigned int selon le type sous-jacent : signed char ou unsigned char (voir ci-dessus) ;

  • wchar_t, char16_t et char32_t peuvent être convertis dans le premier type de la liste suivante capable de contenir la totalité de leur plage de valeurs : int, unsigned int, long, unsigned long, long long, unsigned long ; un type d'énumération non couvert dont le type sous-jacent n'est pas fixe peut être converti dans le premier type de la liste suivante capable de contenir toute la gamme de valeurs : int, unsigned int, long, unsigned long, long long, ou unsigned long. Si la plage de valeurs est supérieure, aucune promotion intégrale ne s'applique ;

  • un type d'énumération non scopé dont le type sous-jacent est fixe peut être converti en son type sous-jacent promu ;

    (depuis C++11)

  • un type de champ binaire peut être converti en int s'il peut représenter toute la plage de valeurs du champ binaire, sinon en unsigned int s'il peut représenter toute la plage de valeurs du champ binaire, sinon aucune promotion intégrale ne s'applique ; le type bool peut être converti en int avec la valeur false devenant 0 et true devenant 1.


Références normalisées (projet de norme actuelle) :

[over.ics.scs] § 3

[prom.conv.] § 1

0 votes

Pourquoi le littéral 0 est-il perçu comme un char au lieu d'un type intégral ?

0 votes

@shasan Le 0 littéral n'est pas perçu comme un caractère. Il est (généralement) "perçu" comme un int. De même, char es un type intégral.

0 votes

Reportez-vous à ma question dans le contexte de la question et de la réponse originales. La question demande pourquoi l'appel de fonction avec 0 appelle la surcharge int. La réponse explique comment "la promotion de char à int est préférée à la conversion de char à short".

23voto

Rakete1111 Points 10248

De Conversion implicite (cppreference) :

Les conversions implicites suivantes sont classées comme des promotions intégrales :

  • [...]
  • char peut être converti en int o unsigned int en fonction du type de sous-jacent : signed char o unsigned char (voir ci-dessus) ;
  • [...]

Ainsi, s'il existe une fonction f(int) y f(short) le compilateur va essayer de faire un promotion entière d'abord, si ce n'est pas possible, il se rabattra sur une conversion en nombres entiers .

char a int est un promotion entière (voir ci-dessus), donc le compilateur le choisira.

S'il n'y a pas de f(int) le compilateur ne trouvera pas de fonction permettant la promotion d'entiers, et se rabattra sur la conversion d'entiers. Il trouve une f(short) et un char peut être converti en un short alors il le choisira.

1 votes

Pourquoi ont-ils utilisé le mot "converti" dans la liste elle-même lorsqu'ils ont établi une différence entre la promotion d'un nombre entier et la conversion ? Cela semble être une source potentielle d'ambiguïté/confusion, surtout lorsqu'il est cité.

0 votes

@JAB bonne question :) Je pense que ce qu'ils veulent dire, c'est que la promotion est un type spécial de conversion. Mais comme il s'agit toujours d'une conversion, ils l'appellent en partie comme ça.

0 votes

Ils établissent que les promotions intégrales entrent dans la catégorie des conversions implicites au début de votre citation, ce qui est logique.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X