Domanda

In Visual Studio C ++ versione 9 (e probabilmente altre versioni troppo), il seguente codice:

int a = sizeof(void);
void const *b = static_cast<void const *>("hello world");
b += 6;

questi errori :

error C2070: 'void': illegal sizeof operand
error C2036: 'const void *' : unknown size

Questo codice funziona in GCC, che tratta sizeof(void) come 1 .

C'è qualche modo a questa limitazione, come colata esplicitamente char * per scopi di puntatori aggiunge alla confusione (void * è ben riconosciuto e usato come un puntatore alla memoria senza tipo grezzo).

Update0

  • Si prega di notare, io sono ben consapevole del esistenza della norma.
  • I vuole per fare puntatore prime aritmetica.
  • Colgo sizeof(void) a mostrare che io sono ben consapevole del fatto che non è 1 è il causa del problema.
  • Il codice esempio è semplicemente quello di dimostrare ciò che è necessaria per generare gli errori.
  • So che questo non è un modo "normale", per usare void, ma questo è C, e queste cose succedono.
  • Sì, la gente ha bisogno di fare questo a basso livello. Io non sono il motivo per cui dopo, sto cercando il modo. Se volete sapere il motivo per cui, date uno sguardo ad alcuni dei sorgenti del kernel, o il vostro glibc amichevole.

Update1

Sembra che questa domanda ha generato una grande confusione. La questione non è di perché avere sizeof(void) == 1 non è standard, ma cosa fare quando non lo è.

Nel caso che puntatore singolo byte aritmetica che deve essere fatto, si scopre che la fusione per char * è la risposta corretta, non perché *(void *) non ha dimensioni, ma perché lo standard di fatto garantisce che *(char *) è sempre 1. Pertanto l'uso di char * è sempre corretta e congruente con void * con l'estensione GCC ai fini del greggio puntatori.

Per rafforzare ulteriormente il punto, void * è la scelta corretta per puntatori a Senza tipo di memoria, e char * sia del tipo a getto a per greggio puntatori .

È stato utile?

Soluzione 8

Sembrerebbe il risposta corretta è utilizzare char * per puntatori, perché sizeof(char) è sempre definita come 1, e ad essere della migliore granularità indirizzabile su qualsiasi piattaforma.

Così, in breve, non v'è alcun modo per aggirare la limitazione, char * è in realtà il modo corretto per farlo.

Matthias Wandel avuto la risposta giusta ma con una giustificazione diversa.

Altri suggerimenti

Incremento un puntatore si suppone tecnicamente ad incrementarlo con qualsiasi dimensione di cosa che la sua punta a. punti vuoto al nulla, quindi la dimensione è sconosciuta.

La sua una finezza per alcuni compilatori per far si incrementa puntatori void.

Casting è fastidioso, perché si deve o lanci a un altro puntatore, e poi di nuovo, o fare qualcosa scomodi come (*(char *)&voidptr) += 6

Personalmente, avevo appena dichiareremo come char * a fini di aritmetica

Nel linguaggio C sizeof non può essere applicato ai tipi incompleti. void è un tipo incompleto, che è il motivo per cui non è possibile utilizzare come operando di sizeof.

Pointer aritmetica dei puntatori void * non è supportata anche in C. Per essere utilizzato con puntatori puntatore ha per puntare ad oggetto tipo, che non è void.

GCC permette sia come un'estensione del linguaggio strano.

void * stanno a significare "puntatore a sconosciuto"

L'aggiunta di 6 a un puntatore nullo è quindi definito, perché si sta chiedendo al compilatore di avanzare il puntatore da "la dimensione di 6 oggetti sconosciuti".

Non si dovrebbe fare di esso.

Ci sono due domande differenti qui. Il primo è per void, e la seconda per void*. Essi sono diversi tipi, e hanno poco in comune accanto al nome.

void viene utilizzato principalmente per le dichiarazioni di funzione / definizioni (come il tipo di ritorno o per significare "non accetta argomenti"). Non si può mai forse avere un oggetto di tipo void. Mai. Quindi è difficile vedere la necessità di scoprire la dimensione di tale oggetto inesistente. comportamento di GCC non è standard, e l'estensione intenzionale . Tuttavia, credo che hanno scelto sizeof(void) == 1 perché lo standard C ++ richiede ogni oggetto a prendere almeno un byte di spazio.

void* significa "puntatore a dati reali, ma senza le informazioni sul tipo di riferimento." E 'del tutto possibile avere void*; e vi imbatterete in loro, un sacco. Tuttavia, poiché le informazioni di tipo viene ignorato non si può manipolare il puntatore molto. Ciò è di progettazione, perché se non sai quello che hai davvero non sa cosa si può fare con esso.

Ma se si desidera trattare la memoria, come un insieme di byte allora char* fa. Un char è un byte, in tutto il mondo. Una stringa di byte è un char*. Se si trova questo strano, uso byte* (dove si definisce byte come qualcosa di simile unsigned char).

Posso vedere l'errore sulla prima linea, almeno -? Avete sizeof (void) e dovrebbe essere sizeof (void *), non

Per puramente punta a dati grezzi e incrementando tale puntatore per il numero di byte che un blocco di dati occupa uso sempre char *. Ho poi rifondere il puntatore a un puntatore struttura di dati rilevanti, una volta che ho bisogno di trattarlo come qualcosa di specifico. Incremento un void * non è portabile tra i compilatori.

  

void * è ben riconosciuto e usato come un puntatore alla memoria senza tipo grezzo.

Una corretta. Non avendo un tipo non significa avere una dimensione sia.

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