Est-ce que « long i = 1; » provoquer une conversion de type implicite en C?
-
18-09-2019 - |
Question
Si je vous écris « long i = 1;
» au lieu de « long i = 1l;
», sera le 1
être reconnu comme int
puis converti implicitement long
?
Modifier Merci à tous. Je vois qu'il n'y a pas de conversion de type. Est-ce aussi le cas avec le suffixe u
(comme 10u
)? Alors quel est l'utilisation de ces l
et u
?
La solution
Le compilateur verra ce que vous essayez d'assigner et définir la valeur à 1 immédiatement. Il n'y a pas de conversion de type qui se produit avec un littéral. Même si vous avez dit long x = 1.0, vous ne verrez pas une conversion de type d'exécution.
Par ailleurs, sur Windows, long et int sont les mêmes donc il n'y aurait pas une conversion de type de toute façon.
[Edit: en dernier commentaire spécifique à Windows; référence enlevée pour préprocesseur]
Autres conseils
Le type de 1
constante est int, donc techniquement une conversion de type sera fait, mais ça va se faire au moment de la compilation et rien ne se perd.
Cependant, considérons l'exemple plus intéressant de:
int main(void)
{
long long i = -2147483648;
long long j = -2147483647 - 1;
printf( " i is %lld, j is %lld\n", i, j);
return(0);
}
Je reçois les résultats suivants de différents compilateurs:
-
MSCV 9 (Version 15.00.21022.08):
i is 2147483648, j is -2147483648
-
GCC (3.4.5):
i is -2147483648, j is 0
-
Comeau (4.3.10.1):
i is 2147483648, j is -2147483648
-
Digital Mars:
i is -2147483648, j is -2147483648
Je ne sais pas encore comment rendre compte des différences. Il pourrait être l'un ou plusieurs de:
- bogues du compilateur
- C90 par rapport à des règles C99 en matière de promotion des opérandes (soutien « de
long long
» est C99, mais certains de ces compilateurs pourrait être la compilation pour C90 avec «long long
» comme une extension) - comportement défini de mise en œuvre
- comportement non défini
FWIW, le comportement de MSVC et Comeau est ce que je pensais - ce qui est quelque chose que beaucoup pourrait encore trouver surprenant. pour la première opération La logique (dans mon esprit) est:
-
-2147483648
se tokenisé comme '-
' et2147483648
-
2147483648
est un entier non signé (puisqu'il ne peut pas entrer dans un int - Je crois que ce qui est différent dans C99) - l'application des résultats de l'opérateur « de
-
» unaire à2147483648
à nouveau en raison des règles arithmétiques non signés - convertir cela en un temps dure longtemps change pas le signe.
La logique de la seconde opération est la suivante:
-
-2147483647
se tokenisé comme '-
' et2147483647
-
2147483647
est un entier signé - soustrayant les résultats de
1
à-2147483648
car il n'y a pas de problème représentant ce nombre - convertir cela en un temps dure longtemps change pas le signe.
La plupart des compilateurs modernes devraient être assez intelligent pour voir que vous attribuer le littéral à un long
, et fera le littéral de ce type au lieu de forcer une conversion préalable à l'affectation.
À peu près sûr que si elle était écrite exactement comme indiqué, il sera équivalent à i = 1 litre; Toute conversion sera effectuée au moment de la compilation.
Cependant, si vous écrivez
longue i = (unsigned int) -1;
alors je ne serai probablement pas ce que vous attendiez.
Les compilateurs d'aujourd'hui reconnaîtront et générer le même résultat.