2012-04-07 21 views
7

Sto guardando attraverso il mio libro di testo e sono un po 'confuso su alcuni del codice che è lì dentro. In una parte, le proprie prestazioni aritmetica dei puntatori nel seguente modo:void * vs char * pointer arithmetic

void* bp; 
... 
bp = (void*)((char*)(bp)+16); 
... 

ma in seguito, che fanno il seguente:

void* bp; 
... 
bp = bp+16; 
... 

mi sento come dovrebbero essere due cose diverse, ma stanno trattando piace la stessa cosa mi sento in questo modo perché, per esempio, se si dovesse fare un accesso agli array (per un array di interi, per esempio), si dovrebbe effettuare le seguenti operazioni

int* a = malloc(n*sizeof(int)); 
... 
q = *(a+1); 
... 

in questo caso, non sono io l'accesso alla prossima 4 byte nell'array intero e non il byte successivo? Allo stesso modo, sento che se ho vuoto * a, allora * (a + 1) dovrebbe essere il successivo 4 byte ... Oppure non è così? Grazie.

+0

Questo secondo esempio non deve essere compilato. –

+1

@OliCharlesworth: non compilerà (o almeno attiverà un avviso) se si compila in modalità conforme. gcc non si conforma di default e implementa l'aritmetica 'void *' come un'estensione. –

risposta

11

È un errore. L'aritmetica su void * non è definita dallo standard, ma alcuni compilatori lo offrono come estensione, comportandosi allo stesso modo di char * per l'aritmetica. Il secondo è formalmente non valido C, ma scivolato attraverso presumibilmente per (cattiva) abitudine.

+0

Quindi il modo corretto per accedere ai successivi 16 byte sarebbe il primo cast in char * e quindi aggiungere 16? Lol, devo cambiare una buona quantità di codice ora. Oh, e ho copiato il primo un po 'di sbagliato, ho fatto un piccolo cambiamento ma non penso che farà la differenza per la mia domanda. – de1337ed

+0

Oppure potresti trasmettere a 'uint64_t *' e aggiungere 2;) Sì, il modo portabile è quello di eseguire il cast di un puntatore a un tipo con dimensione nota e fare un calcolo aritmetico su questo. Se non hai bisogno della portabilità e dei documenti del compilatore che l'aritmetica "void *" funziona in un modo specifico, puoi usarla. Ma ovviamente, ad un certo punto dovrai portarlo su un altro compilatore ... –