E non immagini le conseguenze catastrofiche di questo workaround
Non puoi fare casting da puntatori a interi e viceversa, tranne che per NULL e 0 rispettivamente.Che poi tanti compilatori siano di manica larga, è un altro paio di maniche (!), ma è una pratica scorretta e fuori standard (ISO).
int main(){ void *genericPtr; int a = 3; /*conversione da int a void* */ genericPtr = (void*)a; /*conversione da void* a int */ printf("value of Ptr:%dn",(int)genericPtr); return 0;}
Questo non significa che lo standard ISO lo consenta. Al contrario.Che poi GCC se ne sbatta altamente, non mi stupisce: Embrace, Extend and Extinguish… anche da GCC
Nello standard C89 (http://flash-gordon.me.uk/ansi.c.txt) nella sezione "3.2.2.3 Pointers", non fa alcun riferimento per la conversione da void * ad integer, quindi anticamente era illegale.Nello standard C99 (http://www.open-std.org/jtc1/sc22/wg14/ ... /n1124.pdf pagina 59) invece dice:Citazione5An integer may be converted to any pointer type. Except as previously specified, theresult is implementation-defined, might not be correctly aligned, might not point to anentity of the referenced type, and might be a trap representation.6Any pointer type may be converted to an integer type. Except as previously specified, theresult is implementation-defined. If the result cannot be represented in the integer type,the behavior is undefined. The result need not be in the range of values of any integertype.Quindi il nuovo standard lo permette (non lo sapevo).Comunque ne sconsiglio ancora l'uso (come anche lo standard).
5An integer may be converted to any pointer type. Except as previously specified, theresult is implementation-defined, might not be correctly aligned, might not point to anentity of the referenced type, and might be a trap representation.6Any pointer type may be converted to an integer type. Except as previously specified, theresult is implementation-defined. If the result cannot be represented in the integer type,the behavior is undefined. The result need not be in the range of values of any integertype.
Citazione da: "cdimauro"Questo non significa che lo standard ISO lo consenta. Al contrario.Che poi GCC se ne sbatta altamente, non mi stupisce: Embrace, Extend and Extinguish… anche da GCCQuindi non posso nemmeno fare affidamento su -pedantic ?
Che poi GCC se ne sbatta altamente, non mi stupisce: Embrace, Extend and Extinguish… anche da GCC
struct x{ byte field1[ sizeof(void*) ]; byte field2[ sizeof(void*) ]; byte field3[ sizeof(void*) ];};
struct x gigi;int z = *((int *)(& gigi.field1));char * w = *((char **)(& gigi.field2));
Citazione da: "cdimauro"Che poi GCC se ne sbatta altamente, non mi stupisce: Embrace, Extend and Extinguish… anche da GCCPer favore, non usare quell'articolo come esempio qui...
typedef struct { uint32_t tag; uintptr_t data;} TAG;//...TAG* myTag = FindTag(ListaTAG,TAG_INTEGER); //ricerca sul campo tagif (myTag){//tratto il campo data come un integer}//...TAG* myTag = FindTag(ListaTAG,TAG_ADDRESS); //ricerca sul campo tagif (myTag){ //tratto data come un indirizzo}
Citazione da: "clros"@dsar:ma se uso il tag...perchè dovrei preoccuparmi?Non è il tag che non va (anche se è meglio che il tag avvenga lato compilatore), ma il tipo di dato che vuoi usare per tutto. Ho capito che non ti fidi delle mie argomentazioni, ma se in passato nessuno si è mai sognato di usare un puntatore per il tipo integer un motivo ci sarà stato, no?
@dsar:ma se uso il tag...perchè dovrei preoccuparmi?
... ma te lo dico solo per metterlo nella lista delle cose da NON fare. Se sei arrivato ad una soluzione del genere, ti consiglio di rivalutare il design del tuo software.
Questo è pure ok per i linguaggi procedurali, viene anche usato per ridurre il passaggio di parametri e semplificare il bookkeeping delle funzioni