¿Es 0 un literal decimal o un literal octal?

329

El cero siempre es cero, por lo que no importa. Pero en una discusión reciente con un amigo, dijo que los literales octales casi no se usan hoy. Entonces me di cuenta de que en realidad casi todos los literales enteros en mi código son octales, a saber 0.

¿Es 0un literal octal de acuerdo con la gramática de C ++? ¿Qué dice el estándar?

El único uso real que conozco es para los permisos de archivos Unix.

Yakov Galka
fuente
66
¿Es lo mismo para Java?
Philippe
80
+1 por hacer una pregunta totalmente irrelevante y obtener toneladas de votos a favor :-)
Kerrek SB
64
Creo que la manera de representante instantánea sobre lo que no es una cuestión profunda, sino una cuestión peculiar cuya respuesta iba a aterrizar usted friki CRED en el enfriador de agua :)
Josh
44
Pregunta fabulosa :) Lo busqué en Java Language Spec , y en Java es decimal. La especificación incluso contiene la siguiente cita: Tenga en cuenta que los números octales siempre consisten en dos o más dígitos; 0 siempre se considera un número decimal, no es que importe mucho en la práctica, ya que los números 0, 00 y 0x0 representan exactamente el mismo valor entero.
Tobias Ritzau
14
Estoy casi tentado de publicar una respuesta que diga "Sí, 0 es un literal decimal o un literal octal".
Keith Thompson

Respuestas:

296

Sí, 0es un literal octal en C ++.

Según el estándar C ++:

2.14.2 Literales enteros [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
fuente
39
El otro punto importante es que un literal decimal es un dígito distinto de cero seguido de cero o más dígitos, por lo que no hay ambigüedad.
CB Bailey
3
@MSalters: Con su versión, se tienen que especificar adicionalmente la preferencia: Si tanto octal-literal y decimal-literalson posibles interpretaciones del patrón de bytes, recoger octal-literal. La redacción del estándar oficial no tiene este problema.
Martin Sojka
23
@MSalters: Aún no podría tener un decimal decimal como cualquier número de dígitos, tendría que ser un solo cero o un dígito distinto de cero seguido de cualquier dígito; de lo contrario, cada literal octal podría interpretarse como un literal decimal. Puedo ver el error de compilación, ahora: ERROR: 0 is ambiguous, could be octal zero or could be decimal zero. Consider using (1 - 1) to disambiguate.
CB Bailey
3
@MSalters En su ejemplo, 0123 coincidiría tanto con octal-literal como con decimal-literal, pero tendría diferentes significados en ambos sentidos.
esponjoso
55
@CharlesBailey - FTFY, 1aún siendo octal y todo; P -ERROR: 0 is ambiguous, could be octal zero or could be decimal zero. Consider using (8 - 8) to disambiguate
twalberg
44

Cualquier valor entero con el prefijo 0es un valor octal. Es decir: 01 es octal 1, 010 es octal 10, que es decimal 8, y 0 es octal 0 (que es decimal, y cualquier otro, 0).

Entonces sí, '0' es un octal.

Esa es una simple traducción al inglés del fragmento de gramática en la respuesta de @ Als :-)


Un entero prefijo 0xestá no con el prefijo 0. 0xes un prefijo explícitamente diferente. Aparentemente hay personas que no pueden hacer esta distinción.

Según ese mismo estándar, si continuamos:

 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
fuente
55
"Cualquier valor entero que comience con '0' es un valor octal". No es verdad. Ejemplo: 0xA comienza con '0' y es un valor entero.
Nikolai Ruhe
44
0xNo es una ficha. Un literal entero que comienza con 0xes un token único.
Keith Thompson
44
¿Qué fuente estás citando para esa definición? La palabra "token" se define sintácticamente por los estándares C (N1570 6.4) y C ++ (C ++ 11 2.7 [lex.token]). 0xno califica (Al menos en C, es un número de preprocesamiento (N1570 6.4.8) si no es parte de una constante hexadecimal, pero eso no es un token.)
Keith Thompson
11
Estamos discutiendo la sintaxis de constantes / literales enteros según lo definido por los estándares C y C ++ . ¿Cómo es que la definición de "token" de los estándares no es la más apropiada para usar en este contexto? Su condescendencia insultante es inapropiada. Y si crees que soy un acosador por señalar algo que creo que es un error técnico en tu respuesta, te sugiero que reconsideres el significado de esa palabra. (Nunca respondiste mi pregunta sobre la fuente de tu definición.)
Keith Thompson
44
Si alguien tiene curiosidad, la afirmación de que " Una ficha es una cadena de uno o más caracteres que es importante como grupo " parece ser de este artículo de Wikipedia .
Keith Thompson
-2

Aparentemente, todos los literales enteros que comienzan con cero son de hecho octales. Esto significa que incluye 0 también. Esto hace poca diferencia ya que cero es cero. Pero no saber este hecho puede lastimarte.

Me di cuenta de esto cuando intentaba escribir un programa para convertir números binarios en salida decimal y hexadecimal. Cada vez que daba un número que comenzaba con cero, obtenía un resultado incorrecto (por ejemplo, 012 = 10, no 12).

Es bueno saber esta información para no cometer el mismo error.

MCG
fuente
77
Literales enteros que comienzan con cero pero sin la 'x' después del cero.
luiscubal
55
Una afirmación "sí" sin prueba tampoco es una respuesta.
ligereza corre en órbita el
1
Según esta lógica, 09 es un número octal.
0xc0de
3
@ 0xc0de: No, 09no es un número octal, porque no es un número en absoluto; no coincide con la sintaxis para ningún tipo de literal entero.
Keith Thompson
77
Estoy bastante seguro de que @ 0xc0de sabe que 09no es un número octal. Lo que se dijo fue: " Según esta lógica , 09es un número octal". La implicación es que, dado 09que no es un número octal, la lógica debe estar equivocada.
TRiG