Type des entiers littéraux pas int par défaut?
J'ai simplement répondu à cette question, qui lui a demandé pourquoi l'itération jusqu'à 10 milliards de dollars dans une boucle for prend beaucoup plus de temps (l'OP fait avortée au bout de 10 minutes) que l'itération jusqu'à 1 milliard de dollars:
for (i = 0; i < 10000000000; i++)
Maintenant, ma et beaucoup d'autres " réponse évidente était que c'était dû à la variable d'itération en cours de 32 bits (ce qui n'a jamais atteint 10 milliards de dollars) et la boucle se boucle infinie.
Mais si j'ai compris ce problème, je me demande encore ce qui se passait réellement à l'intérieur du compilateur?
Depuis le littéral n'a pas été ajouté avec un L
, il devrait à mon avis être de type int
, trop, et donc de 32 bits. Donc à cause de débordement, il devrait être normale int
à l'intérieur de la gamme, afin d'être joignable. Effectivement reconnaître qu'il ne peut pas être atteint à partir de int
, le compilateur doit savoir qu'il est de 10 milliards de dollars et donc le voir comme un plus-que-32-bit constant.
Un littéral à obtenir une promotion à un côté (ou au moins la mise en œuvre définies) de la fourchette (au moins 64 bits, dans ce cas) automatiquement, même si pas ajouté une L
et cette norme de comportement? Ou est quelque chose de différent se passe derrière les coulisses, comme UB due au débordement (integer overflow effectivement UB)? Quelques citations de la Norme peut être sympa, le cas échéant.
Bien que la question d'origine était le C, j'apprécie aussi C++ réponses, si différent.
- Version courte: Oui, le compilateur automatiquement favorise les littéraux, si je ne suis pas sûr que c'est un "tout le monde le fait" ou un "c'est obligatoire." Aussi, oui, signée de dépassement d'entier est en fait UB. Je laisse à quelqu'un d'autre à creuser les normes des citations et des tas de la récompense.
- Ce type de variable est "je"?
- En raison de l'OP de la question et de sa solution, il est une variable de 32 bits et j'ai moi-même crois que c'était un
int
ouunsigned int
(est-ce paramètre fait de l'importance ici?). - Chaque fois que vous utilisez "a mon avis", en référence à une règle du langage, c'est un signe que vous devriez vérifier le standard de première.
- En effet, j'ai fait la première devrait avoir fouillé dans la norme au lieu d'aller à la manière paresseuse d'une SORTE de question. Vous pourriez à juste titre de me blâmer pour juste être paresseux.
- Si le corps de la boucle est vide, je serais surpris si un compilateur optimisant ne s'est pas juste la chose entière, indépendamment de la boucle lié.
- En effet, il a dit que c'était son vrai testé exemple et, évidemment, le compilateur n'a pas l'optimiser à l'écart.
Vous devez vous connecter pour publier un commentaire.
Dans la mesure du C++ est concerné:
C++11, [lex.icône] ¶2
Et le Tableau 6, pour les littéraux sans les suffixes et les constantes décimales, donne:
(il est intéressant de noter, pour hexadécimal ou octal constantes également
unsigned
types sont autorisés - mais chacun de venir après le correspondant signé un dans la liste)Donc, il est clair que dans ce cas, la constante a été interprété comme une
long int
(oulong long int
silong int
était trop 32 bits).Avis que "trop gros littéraux" devrait entraîner une erreur de compilation:
(ibidem, ¶3)
qui est rapidement vu dans cet exemple, qui nous rappelle que ideone.com utilise 32 bits compilateurs.
J'ai vu maintenant que la question a été sur le C..., il est plus ou moins le même:
C99, §6.4.4.1
liste qui est la même que dans la norme C++.
Addendum: les deux C99 et C++11 permettent aussi l'littéraux être étendues, les types integer" (c'est à dire d'autres spécifiques à l'implémentation types integer) si tout le reste échoue. (C++11, [lex.icône] ¶3; C99, §6.4.4.1 ¶5 après le tableau)
L
suffixe j'ai souvent vu et utilisé n'est pas que strictement nécessaire? Peut-être que si vous voulez être parfaitement explicite sur le type. Par ailleurs, ce n'ces citations (comme lex.icône) moyenne, sont-ils lieu-titulaires ou a TELLEMENT détruit?long
constante. L' [lex.icône] chose est une référence dans la norme C++, les sections ont à la fois un numéro de section et un identifiant comme ça, et je préfère celui-ci car il est moins facile de copier le mal. 🙂int
par défaut, mais je crois que j'ai confondu avec la signature par défaut.L
suffixe est utile lorsqu'une valeur est assez petit pour tenir dans uneint
, mais vous voulez qu'il soitlong
de toute façon:42L
est de typelong
. Exemple:60 * 60 * 24
est 86400, qui peut déborder siint
est de 16 bits;60L * 60L * 24L
ne débordera pas.De mon projet de norme C marqué ISO/IEC 9899:TC2 Comité de Projet — 6 Mai 2005, les règles sont très semblables à la C++ règles de Matteo trouvé:
LL
suffixe (mais c'est logique).Vous pouvez regarder assembleur, si vous êtes intéressé par la façon dont le compilateur interprète le code.
10000000000:
jusqu'à ce qu'il l'a compilé dans une boucle infinie,
si remplacer 10000000000 avec 10000:
gcc
toujours avec-Wall -Wextra
.