Autore Topic: Passaggio di un numero arbitrario di parametri  (Letto 5384 volte)

Offline clros

  • ASM Lover
  • *****
  • Post: 457
  • Karma: +3/-1
    • Mostra profilo
Re: Passaggio di un numero arbitrario di parametri
« Risposta #15 il: 15 Gennaio 2012, 00:02:49 »
Citazione da: "dsar"
E non immagini le conseguenze catastrofiche di questo workaround
Davvero nn immagino...
Anche perchè, nel mio caso, dall' "altra parte", so benissimo quando il valore è da interpretarsi come indirizzo e quando lo si deve considerare un valore...

Insomma, nn ho capito cosa vuoi dirmi...
« Ultima modifica: 01 Gennaio 1970, 02:00:00 da Guest »
Claudio CP La Rosa

Offline cdimauro

  • Human Debugger
  • *****
  • Post: 4291
  • Karma: +7/-95
    • Mostra profilo
Re: Passaggio di un numero arbitrario di parametri
« Risposta #16 il: 15 Gennaio 2012, 09:53:23 »
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).

Offline clros

  • ASM Lover
  • *****
  • Post: 457
  • Karma: +3/-1
    • Mostra profilo
Re: Passaggio di un numero arbitrario di parametri
« Risposta #17 il: 15 Gennaio 2012, 18:41:24 »
Citazione da: "cdimauro"
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).

Anche io lo credevo prima di provare.
Questo codice:
Codice: [Seleziona]
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;
}

Compila senza alcun warning e funziona perfettamente sotto GCC 4.6.1 (Linux Ubuntu).
Sono state attivate le opzione per fornire tutti i warning (-Wall -WExtra) e il flag per la stretta aderenza allo standard ISO (-pedantic)

EDIT: Provato adesso anche su MSVC++ 2010 (Express Edition). Anche qui nessun warning e funzionamento corretto. Ma su qst compilatore non so come intervenire per chiedere l'aderenza allo standard ISO.
« Ultima modifica: 15 Gennaio 2012, 18:51:14 da clros »
Claudio CP La Rosa

Offline cdimauro

  • Human Debugger
  • *****
  • Post: 4291
  • Karma: +7/-95
    • Mostra profilo
Re: Passaggio di un numero arbitrario di parametri
« Risposta #18 il: 15 Gennaio 2012, 18:47:47 »
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

Offline clros

  • ASM Lover
  • *****
  • Post: 457
  • Karma: +3/-1
    • Mostra profilo
Re: Passaggio di un numero arbitrario di parametri
« Risposta #19 il: 15 Gennaio 2012, 18:55:08 »
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 GCC

Quindi non posso nemmeno fare affidamento su -pedantic ?
« Ultima modifica: 01 Gennaio 1970, 02:00:00 da Guest »
Claudio CP La Rosa

Offline clros

  • ASM Lover
  • *****
  • Post: 457
  • Karma: +3/-1
    • Mostra profilo
Re: Passaggio di un numero arbitrario di parametri
« Risposta #20 il: 15 Gennaio 2012, 19:08:34 »
Citazione da: "dsar"
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:

Citazione
5
An integer may be converted to any pointer type. Except as previously specified, the
result is implementation-defined, might not be correctly aligned, might not point to an
entity of the referenced type, and might be a trap representation.
6
Any pointer type may be converted to an integer type. Except as previously specified, the
result 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 integer
type.
Quindi il nuovo standard lo permette (non lo sapevo).

Comunque ne sconsiglio ancora l'uso (come anche lo standard).

Ok...
« Ultima modifica: 01 Gennaio 1970, 02:00:00 da Guest »
Claudio CP La Rosa

Offline cdimauro

  • Human Debugger
  • *****
  • Post: 4291
  • Karma: +7/-95
    • Mostra profilo
Re: Passaggio di un numero arbitrario di parametri
« Risposta #21 il: 15 Gennaio 2012, 19:47:54 »
Citazione da: "clros"
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 GCC

Quindi non posso nemmeno fare affidamento su -pedantic ?
A quanto pare no.
Citazione da: "dsar"
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:

Citazione
5
An integer may be converted to any pointer type. Except as previously specified, the
result is implementation-defined, might not be correctly aligned, might not point to an
entity of the referenced type, and might be a trap representation.
6
Any pointer type may be converted to an integer type. Except as previously specified, the
result 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 integer
type.
Quindi il nuovo standard lo permette (non lo sapevo).

Comunque ne sconsiglio ancora l'uso (come anche lo standard).
Il casting è garantito soltanto per NULL e 0, mentre per tutto resto dipende dall'implementazione.

Per questo motivo, se si vuole scrivere codice portabile, è meglio evitarli.

Offline clros

  • ASM Lover
  • *****
  • Post: 457
  • Karma: +3/-1
    • Mostra profilo
Re: Passaggio di un numero arbitrario di parametri
« Risposta #22 il: 15 Gennaio 2012, 21:41:45 »
Forse ho trovato quello che mi serve:

http://http://stackoverflow.com/questions/1845482/what-is-uintptr-t-data-type
« Ultima modifica: 01 Gennaio 1970, 02:00:00 da Guest »
Claudio CP La Rosa

Offline Z80Fan

  • Administrator
  • Guru
  • *****
  • Post: 1671
  • Karma: +13/-2
    • Mostra profilo
    • http://z80fan.altervista.org
Re: Passaggio di un numero arbitrario di parametri
« Risposta #23 il: 15 Gennaio 2012, 22:07:44 »
Citazione da: "cdimauro"
Che poi GCC se ne sbatta altamente, non mi stupisce: Embrace, Extend and Extinguish… anche da GCC
Per favore, non usare quell'articolo come esempio qui...
« Ultima modifica: 01 Gennaio 1970, 02:00:00 da Guest »

Offline Z80Fan

  • Administrator
  • Guru
  • *****
  • Post: 1671
  • Karma: +13/-2
    • Mostra profilo
    • http://z80fan.altervista.org
Re: Passaggio di un numero arbitrario di parametri
« Risposta #24 il: 15 Gennaio 2012, 23:59:44 »
idea: dichiara i tuoi campi come:
Codice: [Seleziona]
struct x
{
    byte field1[ sizeof(void*) ];
    byte field2[ sizeof(void*) ];
    byte field3[ sizeof(void*) ];
};
e li usi così:
Codice: [Seleziona]
struct x gigi;

int z = *((int *)(& gigi.field1));
char * w = *((char **)(& gigi.field2));

:mrgreen:
« Ultima modifica: 01 Gennaio 1970, 02:00:00 da Guest »

Offline cdimauro

  • Human Debugger
  • *****
  • Post: 4291
  • Karma: +7/-95
    • Mostra profilo
Re: Passaggio di un numero arbitrario di parametri
« Risposta #25 il: 16 Gennaio 2012, 08:24:39 »
Citazione da: "Z80Fan"
Citazione da: "cdimauro"
Che poi GCC se ne sbatta altamente, non mi stupisce: Embrace, Extend and Extinguish… anche da GCC
Per favore, non usare quell'articolo come esempio qui...
Perché? Si parlava di GCC e standard (ISO), e calza a pennello.

Offline clros

  • ASM Lover
  • *****
  • Post: 457
  • Karma: +3/-1
    • Mostra profilo
Re: Passaggio di un numero arbitrario di parametri
« Risposta #26 il: 16 Gennaio 2012, 14:43:26 »
@dsar:

ma se uso il tag...perchè dovrei preoccuparmi?

Codice: [Seleziona]
typedef struct
{
 uint32_t tag;
 uintptr_t data;
} TAG;

//...
TAG* myTag = FindTag(ListaTAG,TAG_INTEGER); //ricerca sul campo tag
if (myTag)
{
//tratto il campo data come un integer
}
//...
TAG* myTag = FindTag(ListaTAG,TAG_ADDRESS); //ricerca sul campo tag
if (myTag)
{
 //tratto data come un indirizzo
}
« Ultima modifica: 01 Gennaio 1970, 02:00:00 da Guest »
Claudio CP La Rosa

Offline clros

  • ASM Lover
  • *****
  • Post: 457
  • Karma: +3/-1
    • Mostra profilo
Re: Passaggio di un numero arbitrario di parametri
« Risposta #27 il: 16 Gennaio 2012, 19:29:43 »
Citazione da: "dsar"
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?
Ma no, non è per questo!! :D
Non è che non mi fido, cercavo solo di capire a fondo qualcosa che, per mia ignoranza o incapacità mentale, non riesco a comprendere pienamente...e poi insistevo per due motivi:
1) ho già visto il sistema che proponevo qui (o quantomeno un sistema simile)
2) ho già scritto parte del mio codice in questa maniera e non mi andava di riscriverlo! :D
 
 :mrgreen:
« Ultima modifica: 01 Gennaio 1970, 02:00:00 da Guest »
Claudio CP La Rosa

Offline clros

  • ASM Lover
  • *****
  • Post: 457
  • Karma: +3/-1
    • Mostra profilo
Re: Passaggio di un numero arbitrario di parametri
« Risposta #28 il: 19 Gennaio 2012, 10:51:40 »
Citazione da: "dsar"
... 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.

Allora, ho passato 2 giorni a girarmi i pollici (mentre giravano anche altre cose! :mrgreen: ) per pensare a possibili alternative.
Il problema originario è questo: devo trasformare delle funzioni da C++ a C.
In C++ potevo usare l'overloading per cui un stessa funzione aveva 2 o più prototipi.
Es.:
 void myFunct(bool, int,int); //funzione che opera con i dati in memoria
 void myFunct(bool,string,int); //funzione che opera con i dati su disco

Ads devo creare una sola funzione che possa operare sia in memoria che su disco.

A parte la Union con Tag (che mi sconsigliate), mi sono venute in mente queste possibili soluzioni:
1) Scrivo il prototipo della funzione in modo da prevedere tutti i possibili parametri che devono essere passati. All'atto della chiamata, metterò a NULL o a 0 i parametri che non mi interessano. La funzione controlla i parametri e in base a quelli diversi da 0 o da NULL, esegue l'elaborazione in memoria o su disco. Il problema è che in futuro non posso espandere le funzionalità (almeno di non creare una nuova funzione con una nuova firma).
2) Passo alla funzione l'indirizzo di una struttura i cui campi, inizializzati dall'utente, corrispondono ai vari parametri. La funzione analizza i campi e capisce dove deve operare. Questa soluzione, rispetto alla n.1, mi sembra migliore perchè potrei in futuro aumentare i parametri da passare semplicemente cambiando o aumentando il numero dei campi della struttura (ovviamente ogni versione della funzione riuscirà a leggere correttamente solo la corretta versione della struttura).

Cosa ne pensate?
« Ultima modifica: 01 Gennaio 1970, 02:00:00 da Guest »
Claudio CP La Rosa

Offline clros

  • ASM Lover
  • *****
  • Post: 457
  • Karma: +3/-1
    • Mostra profilo
Re: Passaggio di un numero arbitrario di parametri
« Risposta #29 il: 19 Gennaio 2012, 15:34:31 »
Citazione da: "dsar"
Questo è pure ok per i linguaggi procedurali, viene anche usato per ridurre il passaggio di parametri e semplificare il bookkeeping delle funzioni
In questo caso potrei usare alcuni campi della struttura per comunicare al chiamante qualcosa (es: codici di errore)?
« Ultima modifica: 01 Gennaio 1970, 02:00:00 da Guest »
Claudio CP La Rosa

Tags: