type fields c gcc

type - bit fields c



Asignando entero de 128 bits en C (2)

¿Estoy haciendo algo mal o es un error en gcc?

El problema está en la parte 47942806932686753431 , no en __uint128_t p . De acuerdo con los documentos de gcc, no hay forma de declarar una constante de 128 bits:

No hay soporte en GCC para expresar una constante entera de tipo __int128 para objetivos con un entero largo largo de menos de 128 bits.

Por lo tanto, parece que si bien puede tener variables de 128 bits, no puede tener constantes de 128 bits, a menos que su long long sea ​​de 128 bits de ancho.

La solución podría ser construir un valor de 128 bits a partir de constantes integrales "más estrechas" utilizando operaciones aritméticas básicas, y esperar que el compilador realice el plegado constante .

Cuando intento asignar un entero de 128 bits en gcc 4.9.1, warning: integer constant is too large for its type una warning: integer constant is too large for its type .

Código de ejemplo

int main(void) { __uint128_t p = 47942806932686753431; return 0; }

Salida

Estoy compilando con gcc -std=c11 -o test test.c y obtengo:

test.c: In function ‘main’: test.c:2:19: warning: integer constant is too large for its type __uint128_t p = 47942806932686753431; ^

¿Estoy haciendo algo mal o es un error en gcc?


¿Has probado esto?

__int128 p = *(__int128*) "/x00/x01/x02/x03/x04/x05/x06/x07/x08/x09/x0a/x0b/x0c/x0d/x0e/x0f";

EDITAR 25 de noviembre

Perdón por la mala aclaración en el post anterior. En serio, no publiqué esta respuesta como una broma. Aunque el documento de GCC indica que no hay manera de expresar una constante entera de 128 bits, esta publicación simplemente proporciona una solución para aquellos que desean asignar valores a las variables __uint128_t con facilidad.

Puede intentar complicar el código siguiente con GCC (7.2.0) o Clang (5.0.0). Imprime los resultados deseados.

#include <stdint.h> #include <stdio.h> int main() { __uint128_t p = *(__int128*) "/x00/x01/x02/x03/x04/x05/x06/x07/x08/x09/x0a/x0b/x0c/x0d/x0e/x0f"; printf("HIGH %016llx/n", (uint64_t) (p >> 64)); printf("LOW %016llx/n", (uint64_t) p); return 0; }

El stdout:

HIGH 0f0e0d0c0b0a0908 LOW 0706050403020100

Esto solo se considera como una solución alternativa, ya que reproduce los trucos de los punteros al colocar el "valor" en la sección .rodata (si lo objdump) y no es portátil (x86_64 y aarch64 están bien, pero no arman y x86). Creo que ha sido suficiente para aquellos que codifican en máquinas de escritorio.