Newsgroup: it.comp.lang.c
Titolo: Puntatore void

Salve,
non riesco a capire se e' il mio compilatore che e' bacato oppure se sbaglio
ad utilizzare il puntatore void.
Nel K&R a pagina 117 c'e' scritto che il puntatore tipo void* sostituisce il
tipo char* nella dichiarazione di un puntatore generico.
Ebbene io ho dichiarato un puntatore void* per puntare ad una zona di
memoria cui devo accedere un byte alla volta, ma il compilatore continua a
restituirmi degli errori.
Cio' che io ho scritto e':
 void* Ptr_bloc_var;
 Ptr_bloc_var = (void*)&Start;                                   // Inizio
blocco dati da trasferire
 for (temp=0; temp < Bloc_size; temp++)
  {
   byte_wr(*Ptr_bloc_var++,&address);                      // Scrivi un byte
puntato da Ptr_bloc_var in address
  }
Start e Bloc_size sono correttamente inizializzate in un altro punto del
programma.
Il compilatore mi restituisce i seguenti 2 errori:
(E) Illegal type for "++"
(E) Pointer required for "*"
Se invece scrivo:
 unsigned char* Ptr_bloc_var;
 Ptr_bloc_var = (unsigned char*)&Start;                                   //
Inizio blocco dati da trasferire
 for (temp=0; temp < Bloc_size; temp++)
  {
   byte_wr(*Ptr_bloc_var++,&address);                                  //
Scrivi un byte puntato da Ptr_bloc_var in address
  }
Tutto funziona correttamente.
Riuscite a capire dov'e' la mia mancanza ?
Grazie a tutti
--
Ciao
Giuseppe

Ti sei scontrato con un "piccolo" problema...
Se fai
long lng[2];
long *p = &lng;
p++;
p ora non č avanzato di 1 byte, ma di sizeof(long)...
Se lo fai con i char* chiaramente avanza di un byte...
Ma con void di quanto dovrebbe avanzare? void non č un tipo di dato valido
(non puoi dichiarare void p). Puň solo essere usato come puntatore o come
parametro di funzione. Per questo, non essendo valida l'espressione
sizeof(void), il compilatore non sa come far avanzare il pointer. Il
discorso del K&R vale quando tu non devi fare operazioni matematiche sui
puntatori.
Su parecchi compilatori comunque c'č l'opzione per porre sizeof(void) = 1
--- bye


Grazie.
Avevo immaginato una cosa del genere.
Pero' la domanda mi sorge spontanea: ma come fa, ad esempio, la funzione
memset() ad utilizzare il void* ?
Esegue un typecasting ?
Per curiosita' ho provato a fare un typecasting del void a unsigned char,
pero' il compilatore si incacchiava lo stesso ?
Ciao
Giuseppe

 pero' il compilatore si incacchiava lo stesso ?
Evidentemente hai sbagliato qualcosa :-) Semplice vero?
in C void* può essere convertito IMPLICITAMENTE in tutto. In C++ void* può
essere convertito ESPLICITAMENTE in tutto. (mi sembra cmq che i ptr a
funzione facciano eccezione)
--- bye

 Riuscite a capire dov'e' la mia mancanza ?
Non puoi applicare l'operatore * per ottenere il valore puntato di un
puntatore senza tipo, semplicemente perché il compilatore non sa
"quanta" memoria renderti disponibile.  Nel secondo caso tutto
funziona perché "unsigned char" è un tipo di lunghezza 1 (su qualunque
piattaforma).

> Su parecchi compilatori comunque c'è l'opzione per porre
sizeof(void) = 1
Però attenzione, il paragrafo "Constraints" relativo all'operatore
sizeof, dello standard ISO, è preciso in questo:
"the sizeof operator shall not be applied to to an expression that has
function type or an incomplete type, to the parenthesized name of such
a type, or to an lvalue that designates a bit-field object." [Section
6.3.3.4]
Ora, violare la "constraint" è consentito, ma il compilatore *deve*
produrre un messaggio diagnostico, solo in questo caso è conforme allo
standard del linguaggio.

 Esegue un typecasting ?
Non necessariamente.  A parte che void* viene trasformato
implicitamente in qualunque tipo puntatore, la funzione potrebbe ad
esempio essere implementata in assembly built-in e quindi passare il
valore del puntatore direttamente nei registri.