Domanda

è valido

void *p = &X; /* some thing */
p += 12;

E se sì, cosa indica P ora? Ho un codice (di terze parti) che lo fa (e compila in modo pulito) e la mia ipotesi è che il vuoto * sia stato trattato come un carattere *. Il mio fidato K&R è silenzioso (ish) sull'argomento

EDIT: la mia piccola app di test funziona bene su GCC 4.1.1 e tratta void * come char *. Ma g ++ barfs

So come farlo correttamente. Devo sapere se devo pulire questa base di codice per trovare tutti i luoghi.

BTW GCC -Oppetic lancia un avvertimento

Riepilogo:

La specifica C è ambigua. Dice che in termini di rappresentazione e utilizzo come parametri della funzione void* = char*. Ma è silenzioso riguardo all'aritmetica del puntatore.

  • GCC (4) lo consente e lo tratta come char *
  • G ++ lo rifiuta
  • GCC -Pedantic ne avverte
  • VS2010 Sia C che C ++ lo rifiuta
È stato utile?

Soluzione

Dipende dal compilatore. Quelli che lo consentono di considerare la dimensione di ( *(void *)) come 1.

EDIT: è solo per l'aritmetica del puntatore vuoto. Non avrebbe senso usare in questo caso passaggi di dimensione (int) o di 0. Le aspettative comuni di qualcuno che lo usa sarebbe il più piccolo passo possibile.

Altri suggerimenti

No, questo non è legale. UN void* non può essere arbitrariamente incrementato. Deve prima essere lanciato su un tipo specifico.

Se si desidera incrementarlo con un numero specifico di byte, questa è la soluzione che uso.

p = ((char*)p) + 12;

Il char Il tipo è conveniente perché ha una dimensione definita di 1 byte.

MODIFICARE

È interessante notare che funziona su GCC con un avvertimento. Ho testato su Visual Studio 2010 e verificato che non si compila. La mia comprensione limitata dello standard direbbe che GCC nell'errore qui. Puoi aggiungere i seguenti flag di compilation

-Wall -ansi -pedantic

Per citare dalle specifiche:

§6.5.6/2: Per in aggiunta, entrambi gli operandi devono avere un tipo aritmetico o un operando deve essere un puntatore a un tipo di oggetto e l'altro deve avere un tipo di intero. (L'incremento equivale all'aggiunta di 1.)

Un puntatore al vuoto non è un puntatore a un tipo di oggetto, secondo questi estratti:

§6.2.5/1: [...] i tipi sono partizionati in tipi di oggetti (tipi che descrivono completamente gli oggetti), tipi di funzioni (tipi che descrivono le funzioni) e tipi incompleti (tipi che descrivono gli oggetti ma mancano di informazioni necessarie per determinare le loro dimensioni).

§6.2.5/19: Il tipo di vuoto comprende un set vuoto di valori; È un tipo incompleto che non può essere completato.

Pertanto, l'aritmetica del puntatore è non definito per puntatore a vuoto i tipi.

La tua ipotesi è corretta.

Nello standard ISO C99, Sezione 6.2.5 Paragrafo 26, dichiara che i puntatori vuoti e i puntatori del personaggio avranno la stessa rappresentazione e requisiti di allineamento (parafrasando).

Potresti voler dare un'occhiata alla risposta votata in alto per questa domanda

Puntatore aritmetico per puntatore vuoto in c

Non credo che tu possa, perché non ne conosce il tipo, quindi non può cercare la quantità corretta di byte.

Lancialo prima a un tipo, cioè (int).

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