Newsgroup: it.comp.lang.c
Titolo: preprocessore + macro +...

Ciao,
ho un problemino che non so come risolvere.
Premessa sto programmando per un DSP con 4k di RAM e 16k di Flash,
quindi ho le risorse ESTREMAMENTE limitate. Ah e non posso usare
malloc() &c.
Allora ho un struct che dovrebbe essere cosi:
typedef struct
{
    UWord16 		       oldest_index;
    const UWord16	    N;
    Word16			value;
    Word32			sum;
    Word16 			x[N];
}mov_avg_s;
Il problema e' N. N e' il numero di sample della mia moving average.
Quindi decisa a compile time (non cambia durante l'esecuzione).
Il fatto e' che io posso avere N diversi per ogni moving average che
voglio fare.
Esempio:
mov_avg_s corrente, tensione;
per tensione N = 8, mentre per corrente N = 128.
Sarebbe carino avere un metodo per scrivere sta cosa automaticamente,
tipo una macro che mi scrive la definizione della struct per la
corrente e mi dichiara gia' la variabile. Esempio:
CREA_STRUCT_MVG_AVG(variabile,numero_samples);
che dopo la passata dal preprocessore diventa:
struct
{
    UWord16 		       oldest_index;
    const UWord16	    N = numero_samples;
    Word16			value;
    Word32			sum;
    Word16 			x[numero_samples];
}mov_avg_variabile_s;
struct mov_avg_variabile_s variabile;
Sono quasi sicuro che si puo' fare, ma non so come?
C'e' qualcuno che mi puo' dare un hint su come fare? Anche link di
siti con su un po' di esempi un po' complessi.
Grazie Ciao Jack


Non so quanto ti convenga... Comunque, brutalmente, la macro č 
definita cosě:
#define CREA_STRUCT_MVG_AVG(variabile,numero_samples) \
struct\
{\
     UWord16 		       oldest_index;\
     const UWord16	    N = numero_samples;\
     Word16			value;\
     Word32			sum;\
     Word16 			x[numero_samples];\
} mov_avg_##variabile##_s;\
struct mov_avg_##variabile##_s variabile
Ciao.

 definita così:
[CUT]
effettivamente.
il problema che sorge poi e' che ho una fz che mi calcola la moving
average e che come parametro ha la famosa struct.
Pero' chiaramente avro' struct di tipo differente da passargli.
Potrei fare una macro al posto della fz vera e propria, pero' cosi
perdo il riutilizzo del codice, e visto che le risorse son poche...
Boh, non so come fare :(
Ciao Jack

 
definisci una struttura base:
typedef struct
{
     UWord16 		oldest_index;
     const UWord16	N;
     Word16		value;
     Word32		sum;
     Word16 		x[1]; // nota '1'
}mov_avg_s;
che userai come parametro per la funzione.
Tramite macro crei le strutture che ti servono e le passi alla funzione 
facendo un cast alla struttura base.
Nella funzione usi il valore di N per sapere quanti sample devi elaborare.
Ciao

 Ciao
interessante, grazie provero'
Ciao Jack

OK, domanda 2:
allora ho:
#define PLUTO(a,b) typedef a b
che quando la invoco fa:
PLUTO(bla,x);
=> typedef bla x;
pero' vorrei fare una cosa di questio genere:
#define PLUTO(a,b)\
 #define N_##a 10\
 typedef a b
in modo tale che quando la invoco:
PLUTO(bla,x);
=>  #define N_bla 10
    typedef bla x;
Come si puo' fare?
Ciao Jack

Jack ha scritto:

mettendo da parte che non capisco la necessità di una macro per  un 
typedef (a meno che non sia solo come esempio) puoi sostituire la 
seconda #define con un const int. In genere, un compilatore mediamente 
ottimizzante sostituisce la variabile direttamente con il valore 
(essendo costante).
quindi:
  #define PLUTO(a,b)\
   const int N_##a = 10;\
   typedef a b
Ciao

    typedef a b
Per funzionare funziona, ma preferirei se si potesse usare il
preprocessore
Vabbe' scrivo tutto che si fa prima:
allora ho questa (grazie cane):
#define CREA_STRUCT_MVG_AVG(variabile,numero_samples) \
struct\
{\
     UWord16                   oldest_index;\
     const UWord16          N = numero_samples;\
     Word16                     value;\
     Word32                     sum;\
     Word16                     x[numero_samples];\
} mov_avg_##variabile##_s;\
struct mov_avg_##variabile##_s variabile
che viene usata nella dichiarazione delle variabili globali.
il problema e' che mi da' errore ()chiaramente) a questa riga:
const UWord16          N = numero_samples;\
che ho dovuto modifica e far diventare cosi:
UWord16          N;\
quindi devo trovare un modo per istanziare N.
Ho pensato di fare un'altra macro:
#define INIT_STRUCT_MVG_AVG(variabile) \
variabile.oldest_index = 0;\
variabile.N = N_SAMPLES_##variabile;\
variabile.sum = 0
pero' mi pare brutto dover riscrivere il numero_samples com parametro
di questa macro (che andrebbe poi usata nella funzione init()).
Quindi devo trovare un metodo per "passare" alla macro
INIT_STRUCT_MVG_AVG il numero_samples usato dalla CREA_STRUCT_MVG_AVG.
Avevo quindi pensato di fare cosi:
#define CREA_STRUCT_MVG_AVG(variabile,numero_samples) \
#define N_SAMPLES_##variabile numero_samples \
typedef struct\
{\
     UWord16                   	oldest_index;\
     UWord16    		      	N;\
     Word16                     value;\
     Word32                     sum;\
     Word16                     x[numero_samples];\
} mov_avg_##variabile##_s;\
\
mov_avg_##variabile##_s variabile
ma non va come speravo (in effetti non va affatto).
Idee?
Grazie Ciao Jack

Jack ha scritto:
<snip>

visto che fai la dichiarazione e definizione nella macro basta questo:
#define CREA_STRUCT_MVG_AVG(variabile,numero_samples) \
typedef struct\
{\
      UWord16            	oldest_index;\
      UWord16    	     	N;\
      Word16                     value;\
      Word32                     sum;\
      Word16                     x[numero_samples];\
} mov_avg_##variabile##_s;\
\
mov_avg_##variabile##_s variabile = { 0, numero_samples }
e puoi omettere la macro di inizializzazione, o almeno non hai più 
bisogno di assegnare N.
Se togli la definizione dalla macro, la soluzione più semplice è 
ripassare il numero. Ma se usi anche per questo una macro non ci vedo 
nulla di brutto.
es. #define MAX_SAMPLE_VOLT 10 e poi passi questo alle due macro.
Ciao

 es. #define MAX_SAMPLE_VOLT 10 e poi passi questo alle due macro.
ci avevo pensato, ma il codice che sto scrivendo andra' a far parte di
una libreria, quindi vorrei fare le cose il piu' semplici possibile a
chi la usera'. Per questo non volevo far scrivere 2 volte all'luser il
numero di samples ;)
Grazie per l'aiuto
Ciao Jack