0 est-il un littéral décimal ou un littéral octal?

329

Zéro est toujours zéro, donc cela n'a pas d'importance. Mais lors d'une récente discussion avec un ami, il a déclaré que les littéraux octaux n'étaient presque pas utilisés aujourd'hui. Ensuite, il m'est apparu qu'en fait, presque tous les littéraux entiers de mon code sont octaux, à savoir 0.

Un 0octal littéral est-il conforme à la grammaire C ++? Que dit la norme?

La seule utilisation réelle que je connaisse concerne les autorisations de fichiers Unix.

Yakov Galka
la source
6
Est-ce la même chose pour Java?
Philippe
80
+1 pour avoir posé une question totalement hors de propos et obtenu des tonnes de votes positifs :-)
Kerrek SB
64
Je pense que le moyen de rep instantané sur SO n'est pas une question profonde, mais une question particulière dont la réponse vous ferait croire geek au refroidisseur d'eau :)
Josh
4
Terrific question :) Je l'ai recherché dans la spécification du langage Java , et en Java, il est décimal. La spécification contient même la citation suivante: Notez que les chiffres octaux sont toujours constitués de deux chiffres ou plus; 0 est toujours considéré comme un nombre décimal - ce n'est pas très important dans la pratique, car les chiffres 0, 00 et 0x0 représentent tous exactement la même valeur entière.
Tobias Ritzau
14
Je suis presque tenté de poster une réponse qui dit "Oui, 0 est un littéral décimal ou un littéral octal."
Keith Thompson du

Réponses:

296

Oui, 0est un littéral octal en C ++.

Selon la norme C ++:

2.14.2 Littéraux entiers [lex.icon]

integer-literal:  
    decimal-literal integer-suffixopt  
    octal-literal integer-suffixopt  
    hexadecimal-literal integer-suffixopt  
decimal-literal:  
    nonzero-digit  
    decimal-literal digit  
octal-literal:  
    0                           <--------------------<Here>
    octal-literal octal-digit
Alok Save
la source
39
L'autre point important étant qu'un littéral décimal est un chiffre non nul suivi de zéro ou plusieurs chiffres, donc il n'y a pas d'ambiguïté.
CB Bailey
3
@MSalters: Avec votre version, vous devez en plus spécifier la préférence: si les deux octal-literal et decimal-literalsont des interprétations possibles du modèle d'octets, choisissez octal-literal. Le libellé de la norme officielle n'a pas ce problème.
Martin Sojka
23
@MSalters: Vous ne pouvez toujours pas avoir de littéral décimal comme n'importe quel nombre de chiffres, il faudrait que ce soit un seul zéro ou un chiffre non nul suivi de n'importe quel chiffre sinon chaque littéral octal pourrait être interprété comme un littéral décimal. Je peux voir l'erreur de compilation, maintenant: ERROR: 0 is ambiguous, could be octal zero or could be decimal zero. Consider using (1 - 1) to disambiguate.
CB Bailey
3
@MSalters Dans votre exemple, 0123 correspondrait à la fois au littéral octal et au littéral décimal, mais aurait des significations différentes dans les deux cas.
moelleux
5
@CharlesBailey - FTFY, avec 1toujours être octal et tout; P -ERROR: 0 is ambiguous, could be octal zero or could be decimal zero. Consider using (8 - 8) to disambiguate
twalberg
44

Toute valeur entière précédée d' 0un préfixe est une valeur octale. Ie: 01 est octal 1, 010 est octal 10, qui est décimal 8, et 0 est octal 0 (qui est décimal, et tout autre, 0).

Alors oui, «0» est un octal.

C'est une traduction anglaise simple de l'extrait de grammaire dans la réponse de @ Als :-)


Un entier préfixé par 0xn'est pas préfixé par 0. 0xest un préfixe explicitement différent. Apparemment, il y a des gens qui ne peuvent pas faire cette distinction.

Selon cette même norme, si nous continuons:

 integer-literal:
     decimal-literal integer-suffixopt
     octal-literal integer-suffixopt
     hexadecimal-literal integer-suffixopt
 decimal-literal:
     nonzero-digit                       <<<---- That's the case of no prefix.
     decimal-literal digit-separatoropt digit
 octal-literal:
     0                                    <<<---- '0' prefix defined here.
     octal-literal digit-separatoropt octal-digit <<<---- No 'x' or 'X' is
                                                          allowed here.
 hexadecimal-literal:
     0x hexadecimal-digit                 <<<---- '0x' prefix defined here
     0X hexadecimal-digit                 <<<---- And here.
     hexadecimal-literal digit-separatoropt hexadecimal-digit
littleadv
la source
5
"Toute valeur entière commençant par '0' est une valeur octale." Pas vrai. Exemple: 0xA commence par «0» et est une valeur entière.
Nikolai Ruhe
4
0xn'est pas un jeton. Un littéral entier commençant par 0xest un seul jeton.
Keith Thompson du
4
Quelle source citez-vous pour cette définition? Le mot "token" est défini syntaxiquement par les normes C (N1570 6.4) et C ++ (C ++ 11 2.7 [lex.token]). 0xn'est pas admissible. (Au moins en C, c'est un nombre de prétraitement (N1570 6.4.8) s'il ne fait pas partie d'une constante hexadécimale, mais ce n'est pas un jeton.)
Keith Thompson
11
Nous discutons de la syntaxe des constantes / littéraux entiers tels que définis par les normes C et C ++ . Comment la définition de «jeton» des normes n'est-elle pas la plus appropriée à utiliser dans ce contexte? Votre condescendance insultante est inappropriée. Et si vous pensez que je suis un tyran pour avoir signalé quelque chose que je pense être une erreur technique dans votre réponse, je vous suggère de reconsidérer le sens de ce mot. (Vous n'avez jamais répondu à ma question sur la source de votre définition.)
Keith Thompson
4
Si quelqu'un est curieux, la déclaration selon laquelle " un jeton est une chaîne d'un ou plusieurs caractères qui est significative en tant que groupe. " Semble provenir de cet article Wikipedia .
Keith Thompson du
-2

Apparemment, tous les littéraux entiers commençant par zéro sont en fait octaux. Cela signifie qu'il inclut également 0. Cela fait peu de différence puisque zéro est zéro. Mais ne pas savoir ce fait peut vous blesser.

Je l'ai réalisé lorsque j'essayais d'écrire un programme pour convertir des nombres binaires en sortie décimale et hexidécimale. Chaque fois que je donnais un nombre commençant par zéro, j'obtenais la mauvaise sortie (par exemple, 012 = 10, pas 12).

Il est bon de connaître ces informations afin de ne pas commettre la même erreur.

MCG
la source
7
Littéraux entiers commençant par zéro mais sans le «x» après le zéro.
luiscubal
5
Une affirmation «oui» sans preuve n'est pas non plus une réponse.
Courses de légèreté en orbite
1
Selon cette logique, 09 est un nombre octal.
0xc0de
3
@ 0xc0de: Non, ce 09n'est pas un nombre octal, car ce n'est pas du tout un nombre; il ne correspond à la syntaxe d'aucun type de littéral entier.
Keith Thompson
7
Je suis assez confiant que @ 0xc0de sait que ce 09n'est pas un nombre octal. Ce qui a été dit était: " Selon cette logique , 09c'est un nombre octal." L'implication est que, puisqu'il 09n'est pas un nombre octal, la logique doit être erronée.
TRiG