Utilizzo di macro per proteggere l'assegnazione alle variabili globali

5

Poiché non esiste una caratteristica linguistica in C per proteggere l'assegnazione alle variabili globali, consiglieresti di fare qualcosa del genere?

Prendi questo esempio:

We have a module with the header file called module.h and implementation file module.c. The module contains a global variable called global_variable. global_variable will be updated by other functions in the implementation but we do not want users of module to be able to assign to it.

module.h:

#ifndef MODULE_H_
#define MODULE_H_

extern int global_variable;
#define global_variable (int)global_variable
/* Because the macro expansion is not an "lvalue" it cannot be assigned to. */

/* ... */

#endif

Nell'implementazione hai appena #undef della macro per avere accesso completo in lettura / scrittura ad esso.

module.c:

#include "module.h"
#undef global_variable /* Make 'global_variable' mutable again. */

int global_variable = 17;

/* ... */

Questo metodo ha ovviamente lo svantaggio di non poter creare una variabile locale con l'identificatore global_variable senza #undef ing della macro.

#include "module.h"

int f(void)
{
    int global_variable; /* This doesn't work. */
    /* ... */
}

Ma se riesci a trovare una convenzione di denominazione che separi gli identificatori, questo non sarà un problema. Qualcosa come il prefisso delle variabili globali con glbl_ o GLBL_ . GLBL_ sembra una buona scelta dato che ti dà anche un suggerimento che può essere definita come una macro.

Un'altra tecnica che ho capito è questa:

module.h:

#ifndef MODULE_H_
#define MODULE_H_

#ifdef MODULE_IMPL_
extern int global_variable; /* Writable for the implementation. */
#else
extern const int global_variable; /* 'readonly' for everyone else. */
#endif

/* ... */

#endif

module.c:

#define MODULE_IMPL_ /* I am the implementation. I want global_variable to be mutable. */
#include "module.h"

int global_variable = 17;

/* ... */

So che l'approccio più semplice e flessibile è quello di creare funzioni get per recuperare il valore della variabile al costo di una chiamata di funzione. Ma questo non mi impedisce di trovare altri hack per risolvere il problema.

Queste cose cattive sono da fare? Non ho intenzione di mentire, mi piace giocare con i macro. Ma voglio sapere se questo è qualcosa che può essere applicato a un progetto serio. :)

    
posta wefwefa3 06.01.2015 - 14:39
fonte

1 risposta

11

Usare le macro per creare codice sintatticamente identico a C ma semanticamente diverso è quasi sempre malvagio, specialmente in un linguaggio non sicuro come C, in cui il fatto che qualcosa compili non garantisce in alcun modo che abbia effettivamente un comportamento definito in fase di esecuzione. Se devi utilizzare una macro per qualcosa, in genere vuoi chiarire che viene utilizzata una macro.

In questo caso specifico puoi raggiungere il tuo obiettivo meglio non esponendo la variabile (cioè rendi static ) e fornendo una funzione per leggere il suo valore. Si ottiene lo stesso risultato finale (il valore è di sola lettura al di fuori del file di implementazione), ma evitare del tutto l'uso di macro e dei relativi inconvenienti. Ancora meglio, non usare una variabile globale se possibile; passa il valore alle funzioni che ne hanno bisogno.

    
risposta data 06.01.2015 - 16:42
fonte

Leggi altre domande sui tag