viceversa traductor sistema numeros hexadecimales hexadecimal ejemplos conversion binario c parsing gcc c99

traductor - Convenciones para escribir adiciones simples de números hexadecimales y decimales.



sistema hexadecimal ejemplos (2)

A pesar de ser un veterano, me temo que ya no tengo (ya) una comprensión completa del análisis de constantes en C. El segundo de los siguientes 1-liners no compila:

int main( void ) { return (0xe +2); } int main( void ) { return (0xe+2); }

$ gcc -s weird.c

weird.c: In function ‘main’: weird.c:1:28: error: invalid suffix "+2" on integer constant int main( void ) { return (0xe+2); } ^

El motivo de la falla de la compilación es probablemente que 0xe + 2 se analiza como una constante de punto flotante hexadecimal según la cláusula 6.4.4.2 de la norma C11. Mi pregunta es si existe una convención para escribir sumas simples de números hexadecimales y decimales en C, no me gusta tener que depender del espacio en blanco en el análisis.

Esto fue con gcc versión 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1 ~ 16.04.9). La detención de la compilación después del preprocesamiento (-E) muestra que la falla de compilación ocurre en gcc no en cpp.


Mi pregunta es si existe una convención para escribir sumas simples de números hexadecimales y decimales en C

La convención es utilizar espacios. Esto es realmente requerido por C11 6.4 §3:

Los tokens de preprocesamiento pueden estar separados por espacios en blanco; consiste en comentarios (descritos más adelante), o caracteres de espacio en blanco (espacio, tabulación horizontal, nueva línea, tabulación vertical y avance de página), o ambos.

Donde el espacio liso es el de uso común.

Problemas similares exóticos existen aquí y allá en el lenguaje, algunos ejemplos:

  • ---a debe ser reescrito como - --a .
  • a+++++b debe reescribirse como a++ + ++b .
  • a /// comment
    b;
    debe ser reescrito como
    a / // comment
    b

Y así. El culpable en todos estos casos es el analizador de fichas que sigue la llamada "regla de munch máxima", C11 6.4 §4:

Si el flujo de entrada se ha analizado en tokens de preprocesamiento hasta un carácter determinado, el siguiente token de preprocesamiento es la secuencia más larga de caracteres que podrían constituir un token de preprocesamiento.

En este caso específico, el preprocesador no hace ninguna distinción entre las constantes de punto flotante y las constantes de enteros, cuando construye un token de preprocesamiento llamado pp-number , definido en C11 6.4.8:

pp-numero e signo
pp-numero E signo
pp-numero p signo
signo pp numero
número de pp .

Un número de preproceso comienza con un dígito opcionalmente precedido por un punto (.) Y puede ir seguido de caracteres identificadores válidos y las secuencias de caracteres e +, e-, E +, E-, p +, p-, P + o P-.

Aquí, el número pp no tiene que ser una constante de punto flotante, en lo que respecta al preprocesador.

(Como nota al margen, también existe una convención similar al terminar secuencias de escape hexadecimales dentro de cadenas. Si, por ejemplo, quiero imprimir la cadena "ABBA" en una nueva línea, entonces no puedo escribir

puts("/xD/xABBA"); (CR + LF + cadena)

Porque la cadena en este caso podría interpretarse como parte de la secuencia de escape hexadecimal. En su lugar, tengo que usar espacios en blanco para finalizar la secuencia de escape y luego confiar en la concatenación de cadenas del preprocesador: puts("/xD/xA" "BBA") . El propósito es el mismo, para guiar al preprocesador a analizar el código. )


Porque GCC piensa que 0xe+2 es un número de punto flotante, mientras que esto es solo una suma de dos enteros.

Según cppreference :

Debido a la munch máxima, las constantes enteras hexadecimales que terminan en e y E , cuando son seguidas por los operadores + o - , deben separarse del operador con espacios en blanco o paréntesis en la fuente:

int x = 0xE+2; // error int y = 0xa+2; // OK int z = 0xE +2; // OK int q = (0xE)+2; // OK