I macro sono considerati una cosa buona da uno e il male da un altro.
C'è una regola empirica quando e quando non usare le macro in C ++?
Quando sono le macro idiomatiche e quando dovrebbero essere evitate?
When are macros idiomatic and when should they be avoided?
Le macro sono idiomatiche solo quando non ci sono alternative al loro uso. Gli esempi includono guardie (sono l'unica forma portatile), linguaggi specifici di domini incorporati, supporto speciale del compilatore non disponibile attraverso altre funzionalità linguistiche (incorporando macro incorporate come __FILE__
, stringificando e concatenando gli identificatori) e alcuni altri luoghi .
Le macro dovrebbero essere evitate quando possibile. Questo perché seguono la loro sintassi molto semplicistica e non sanno nulla di C ++, calpestando silenziosamente qualsiasi spazio dei nomi.
È sempre stato uno degli obiettivi di Stroustrup eliminare il preprocessore il più possibile. Le funzioni di inlining, template e costanti sono un ottimo esempio, così come i moduli (per sostituire #include
), che sono stati masticati per anni dal comitato di standardizzazione. Le funzionalità linguistiche create per evitare di dover utilizzare macro sono tutte molto migliori delle macro che sostituiscono. Usali quando è possibile.
Come regola, dovresti usare solo macro, quando non esiste un'alternativa migliore.
Loro non dovrebbero essere usati per generare codice; dovresti semplicemente scrivere il codice invece (se il codice è di tipo agnostico, scrivi invece un modello).
Loro non dovrebbero essere usati per definire le costanti; le costanti dovrebbero essere definite utilizzando una di queste variabili: (statiche) constexpr / const, enumerazioni anonime, enumerazioni con nome, classi enumerate (a seconda di cosa si desidera utilizzarle).
Loro dovrebbero essere usati per la compilazione condizionale (includi le guardie sono uno di questi casi).
Idealmente, non dovrebbe essere usato per modificare condizionalmente l'API di un modulo alla compilazione (cioè, idealmente dovresti dichiarare le stesse funzioni in tutte le configurazioni, quindi usare la compilazione condizionale nel file di implementazione .
In tutti gli * altri casi, le macro dovrebbero essere evitate.
(*) - A volte, ci sono eccezioni a "tutti gli altri casi" (ad esempio, potresti avere un codice di terze parti che richiede l'utilizzo di macro, che è la vita :-)).
L'unica volta che considererei le macro sono per le costanti di tempo di compilazione, in genere quelle che influiscono sulla compilazione (a differenza dei valori di applicazione costanti, che sono meglio modellati come tipi const).
Tuttavia, ho modellato routine di utilità come le chiamate alle funzioni di logging in una macro solo per essere compilate, ma penso che anche questo non sia necessario oggi - il compilatore dovrebbe essere abbastanza intelligente da realizzare una funzione di logging che non fa nulla a causa della compilazione condizionale sarà ottimizzato, ma le vecchie abitudini sono dure a morire:)