Pregunta

¿Cómo se puede realizar de forma portátil aritmética de punteros con la precisión de un solo byte?

Tenga en cuenta que:

  • char no es de 1 byte en todas las plataformas
  • sizeof(void) == 1 sólo está disponible como una extensión de GCC
  • Si bien algunas plataformas pueden tener puntero DEREF restricciones de alineación de punta, la aritmética todavía pueden requerir una granularidad más fina que el tamaño del tipo POD fundamental más pequeño
¿Fue útil?

Solución

Su suposición es errónea - sizeof(char) es definido a ser de 1 en todas partes

.

Desde el C99 estándar (TC3) , en la sección 6.5.3.4 ( "El operador sizeof"):

(párrafo 2)

  

El operador sizeof produce el tamaño   (En bytes) de su operando, que puede   ser una expresión o la   nombre entre paréntesis de un tipo.

(párrafo 3)

  

Cuando se aplica a un operando que tiene   tipo char, unsigned char, o firmado   char, (o una versión calificada   de la misma) el resultado es 1.

Cuando éstas se toman en conjunto, se hace evidente que en C, sea cual sea el tamaño de un char es, que el tamaño es un "byte" (incluso si eso es más de 8 bits, en alguna plataforma dada).

A char por lo tanto, es el tipo direccionable más pequeño. Si usted necesita para hacer frente en unidades más pequeñas que un char, su única opción es leer una char a la vez y utilizar operadores de bits para enmascarar las partes de la char que desee.

Otros consejos

sizeof(char) siempre devuelve 1, en C y C ++ . Un char es siempre un byte de longitud.

De acuerdo con la char estándar es el trozo direccionable más pequeña de datos. Usted simplemente no puede hacer frente con mayor precisión -. Lo que tendría que hacer el embalaje / desembalaje manualmente

sizeof(char) se garantiza que se 1 por la norma C. Incluso si utiliza char 9 bits o más.

Por lo que puede hacer:

type *pt;
unsigned char *pc = (unsigned char *)pt;

Y el uso de pc para la aritmética. Asignar a pc pt utilizando el elenco anterior es un comportamiento no definido por la norma C embargo.

Si char es más de 8 bits de ancho, no se puede hacer bytes precisión aritmética de punteros en el portátil (ANSI / ISO) C. En este caso, por bytes , me refiero a 8 bits. Esto se debe a que el propio tipo fundamental es mayor que 8 bits.

Reparto el puntero a una uintptr_t. Este será un entero sin signo que es el tamaño de un puntero. Ahora haga su aritmética en él, a continuación, emitir el resultado de nuevo a un puntero del tipo que desea eliminar la referencia.

(Tenga en cuenta que intptr_t está firmado, que por lo general no es lo que quiere! Es más seguro que se adhieren a uintptr_t a menos que tenga una buena razón para no hacerlo!)

No entiendo lo que está intentando decir con sizeof(void) siendo 1 en GCC. Mientras que el tipo char teóricamente podría consistir en más de 1 byte de la máquina subyacente, en C sizeof(char) lenguaje es 1 y siempre exactamente 1. En otras palabras, desde el punto de vista del lenguaje C, char es siempre 1 "byte" (C-byte, no byte de la máquina). Una vez que entienda esto, también se entendería que sizeof(void) siendo 1 en GCC no le ayuda de alguna manera. En GCC la aritmética de punteros sobre punteros void * funciona exactamente de la misma manera que en la aritmética de punteros punteros char *, lo que significa que si en alguna char * plataforma no funciona para usted, entonces void * no va a funcionar para usted tampoco.

Si en alguna plataforma objetos char consisten en múltiples bytes de la máquina, la única manera de acceder a unidades más pequeñas de memoria de la que un objeto char completo sería utilizar operaciones bit a bit a "extraer" y "modificar" las porciones requeridas de un char completa objeto. lenguaje C no ofrece ninguna manera de abordar directamente algo más pequeño que char. Una vez más char siempre es un C-byte.

El estándar C99 define el uint8_t que es de un byte de largo. Si el compilador no admite este tipo, se podría definir usando un typedef. Por supuesto que se necesita una definición diferente, dependiendo de la plataforma y / o compilador. Empaquetar todo en un archivo de cabecera y usarlo en todas partes.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top