Domanda

Come si può portabile eseguire l'aritmetica dei puntatori con precisione singola byte?

Tenga presente che:

  • char non è 1 byte su tutte le piattaforme
  • sizeof(void) == 1 è disponibile solo come estensione in GCC
  • Anche se alcune piattaforme possono avere puntatore deref restrizioni di allineamento puntatore, l'aritmetica possono ancora bisogno di una granularità più fine rispetto alla dimensione del più piccolo tipo POD fondamentale
È stato utile?

Soluzione

La tua ipotesi è difettoso - sizeof(char) è definiti per essere 1 in tutto il mondo

.

C99 standard (TC3) , nella sezione 6.5.3.4 ( "L'operatore sizeof"):

(paragrafo 2)

  

L'operatore sizeof produce la dimensione   (In byte) del suo operando, che può   essere un'espressione o la   nome tra parentesi di un tipo.

(paragrafo 3)

  

Quando viene applicato a un operando che ha   tipo char, unsigned char, o firmati   char, (o una versione qualificato   esso) il risultato è 1.

Quando questi sono presi insieme, diventa chiaro che in C, qualsiasi dimensione un char è che la dimensione è un "byte" (anche se è più di 8 bit, in un dato piattaforma).

A char è quindi del tipo indirizzabile più piccola. Se è necessario affrontare in unità più piccole di una char, l'unica scelta è quella di leggere un char alla volta e utilizzare gli operatori bit a bit per mascherare le parti del char che si desidera.

Altri suggerimenti

sizeof(char) restituisce sempre 1, sia in C e C ++ . Un char è sempre lungo un byte.

Secondo il char di serie è il più piccolo pezzo indirizzabile di dati. Non ci si può affrontare con maggiore precisione -. Si avrebbe bisogno di fare imballaggio / disimballaggio manualmente

sizeof(char) è garantito per essere 1 dallo standard C. Anche se char utilizza 9 bit o più.

Così si può fare:

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

E utilizzare pc per l'aritmetica. Assegnazione pc a pt utilizzando il cast sopra è un comportamento indefinito dallo standard C però.

Se char è larga più di 8-bit, non si può fare di byte precisione aritmetica dei puntatori a portatili (ANSI / ISO) C. Qui, da byte , voglio dire 8 bit. Questo perché il tipo fondamentale stessa è più grande di 8 bit.

Cast il puntatore in una uintptr_t. Questo sarà un numero intero senza segno che è la dimensione di un puntatore. Ora fare il vostro aritmetica su di esso, poi gettato il risultato di nuovo a un puntatore del tipo che si desidera dereference.

(Si noti che intptr_t è firmato, che di solito non è ciò che si vuole! E 'più sicuro di attenersi a uintptr_t meno che non abbiate una buona ragione per non!)

Non capisco che cosa si sta cercando di dire con sizeof(void) essendo 1 in GCC. Mentre il tipo char potrebbe teoricamente consistere di più di 1 byte macchina sottostante, in linguaggio C sizeof(char) è 1 e sempre esattamente 1. In altre parole, dal punto di vista del linguaggio C, char è sempre 1 "byte" (C-byte, non machine byte). Una volta capito questo, si sarebbe anche capire che sizeof(void) essendo 1 in GCC non vi aiutare in qualsiasi modo. Nel GCC aritmetica puntatore puntatori void * funziona esattamente allo stesso modo in cui l'aritmetica dei puntatori a puntatori char *, il che significa che, se su qualche piattaforma char * non funziona per voi, allora void * non funzionerà neanche per te.

Se su qualche piattaforma oggetti char costituiti da più byte macchina, l'unico modo per accedere piccole unità di memoria di un oggetto char completo sarebbe usare operazioni bit per bit a "estrarre" e "modifica" le porzioni richieste di un char completo oggetto. linguaggio C non offre alcun modo di affrontare direttamente qualsiasi cosa più piccolo di char. Ancora una volta char è sempre un C-byte.

Lo standard C99 definisce l'uint8_t che è di un byte. Se il compilatore non supporta questo tipo, è possibile definire utilizzando un typedef. Naturalmente si avrebbe bisogno di una definizione diversa, a seconda della piattaforma e / o compilatore. Bundle tutto in un file di intestazione e usarlo ovunque.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top