Pourquoi le compilateur fait correspondre “char” à “int” mais pas “short”?

J’ai un petit programme:

#include 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 senti que, si c’est à cause de la “promotion entière”, pourquoi n’est-ce pas short préféré?

Je sais aussi que la promotion des nombres entiers se produit dans une expression (comme A = B). Mais je n’ai pas d’expression en appel à f(), non?

Si cela est lié à la règle de résolution de la surcharge, pourquoi le passage de char à f se traduira-t-il par des compilateurs préférant int au shortshort ?

Si je supprime f(int) , alors f(c) appellera f(short) !

Donc, en résumé, ma question est la suivante: est-ce lié à la “promotion d’entier” ou simplement à la “règle de résolution de surcharge”? Et pourquoi?

    La promotion (intégrale) est préférable à la conversion (intégrale) par résolution de surcharge

    Classement des séquences de conversion implicites

    1) Correspondance exacte: pas de conversion requirejse, conversion 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 à virgule flottante

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

    Ainsi, la promotion de char à int est préférable à la conversion de char à short .


    Qu’est ce que la promotion? tu peux demander. C’est un type particulier de conversion décrit par la norme.

    Pourquoi le char short pas une promotion? , vous pouvez continuer. La promotion intégrale est toujours de type int ou plus grand. Il n’y a pas de promotions à short .

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

    • char signé ou short signé peut être converti en int;

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

    • char peut être converti en int ou unsigned int en fonction du type sous-jacent: char signé ou caractère non signé (voir ci-dessus);

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

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

      (depuis C ++ 11)

    • un type de champ de bits peut être converti en int s’il peut représenter une plage de valeurs entière du champ de bits, sinon dans unsigned int s’il peut représenter une plage de valeurs complète du champ de bits; le type bool peut être converti en int avec la valeur false devenant 0 et true devenant 1.


    Références standard (projet standard actuel):

    [over.ics.scs] § 3

    [conv.prom] § 1

    De la conversion implicite (cppreference):

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

    • […]
    • char peut être converti en int ou unsigned int fonction du type sous-jacent: signed char ou caractère unsigned char (voir ci-dessus);
    • […]

    Donc, s’il y a une fonction f(int) et f(short) , le compilateur essaiera d’abord de faire une promotion entière , si ce n’est pas possible, il se tournera vers une conversion entière .

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

    S’il n’y a pas de f(int) , le compilateur ne parviendra pas à trouver une fonction permettant de faire de la promotion sur les entiers et utilisera la conversion en entier. Il trouve un f(short) , et un caractère peut être converti en un short , ainsi il le choisira.