Funzione wrapper o aliasing con un'unione?

3

Ho una struttura che potrebbe avere altri 2 membri a seconda della variabile del preprocessore.

struct foo {
    int m1;
    // ... (other members)
    #ifdef MORE_MEMBERS
    int m2;
    int m3;
    #endif
}

In alcune parti del codice, ho bisogno di cambiare alcune chiamate di funzione da func(foo.m1) a func(foo.m1, foo.m2, foo.m3) . Gli ultimi due argomenti saranno ignorati se MORE_MEMBERS non è definito, ma ricevo comunque errori di compilazione dalle chiamate di funzione.

Posso pensare a due soluzioni:

(1) Usa un'unione. m2 e m3 saranno solo alias su m1 .

struct foo {
    #ifdef MORE_MEMBERS
    int m1, m2, m3;
    #else
    union {
        int m1, m2, m3;
    }
    #endif
    // ... (other members)
}

(2) Usa una funzione wrapper, mantenendo la definizione della struttura senza unione.

func2(foo) {
    #ifdef MORE_MEMBERS
        func(foo.m1, foo.m2, foo.m3);
    #else
        func(foo.m1);
    #endif
}

Cosa sarebbe meglio nel file con le chiamate alle funzioni modificate? Una modifica di func(int) in func(int,int,int) o func(int) in func2(foo) .

    
posta devil0150 18.02.2017 - 16:25
fonte

1 risposta

3

Primo suggerimento non farlo! Le compilazioni condizionali sono una grande fonte di bug e amp; hard; misteriosi arresti. Uno di questi esempi è quando parte del tuo codice è stata compilata con define in place e un'altra senza.

È quasi sempre meglio incorporare il tipo all'interno dei dati, quindi la tua struttura dovrebbe essere:

  • essere definito come un tipo con typedef , una buona regola empirica è quella di creare sempre strutture di tipi denominati, quindi il compilatore può digitare il controllo per te .
  • contiene un enumerato per la variante, membro enums invece di numeri magici o #defines e di nuovo crea quei tipi nominati in modo che tu possa vedere quando vengono usati in modo improprio
  • quindi contiene un union delle varianti a variabile singola e multipla.

Puoi quindi passare un singolo parametro digitato alla tua funzione che lo elaborerà in modo diverso in base alla Variante. Quindi il tuo compilatore ti dirà se la funzione viene mai chiamata con qualcosa di diverso.

Da un punto di vista qualitativo la compilazione condizionale è cattive notizie e dovrebbe essere riservata per cose come piattaforma e amp; varianti specifiche del compilatore solo . Dal punto di vista del test, a meno che non crei il tuo codice con ogni combinazione di interruttori e test con ciascuno, non puoi dire di avere una copertura del 100% del codice anche quando i tuoi strumenti dicono che lo hai.

    
risposta data 18.02.2017 - 17:17
fonte

Leggi altre domande sui tag