Preprocessore macro espansione ad un'altra direttiva del preprocessore
-
12-09-2019 - |
Domanda
Inizialmente ho pensato che avrei bisogno di questo, ma alla fine ho evitato. Tuttavia, la mia curiosità (e l'appetito per la conoscenza, hum) mi fanno chiedere:
Può una macro di preprocessore, ad esempio in
#include "MyClass.h"
INSTANTIATE_FOO_TEMPLATE_CLASS(MyClass)
espandersi per includere un altro, come in
#include "MyClass.h"
#include "FooTemplate.h"
template class FooTemplate<MyClass>;
?
Soluzione
Credo che non può essere fatto, questo è perché il pre-processore è singolo passaggio . Quindi non può emettere altre direttive del preprocessore.
In particolare, dal C99 standard (6.10.3.4 comma 3):
3 La risultante completamente macro-sostituito di pre-elaborazione di token sequenza non viene elaborata come direttiva al preprocessore anche se assomiglia a uno, ...
È interessante notare che questo è il motivo per cui l'operatore _Pragma
unario è stato aggiunto al C99. Perché #pragma
non poteva essere emited dalle macro, ma _Pragma
can.
Altri suggerimenti
Lo standard C dice questo circa la pre-elaborazione delle direttive (C99 - 6.10 (2) - direttive al preprocessore):
Una direttiva di pre-elaborazione è costituito da una sequenza di token pre-elaborazione che inizia con un segno # pre-elaborazione che (all'inizio della fase di traduzione 4) ...
e (C99 - 6.10 (7)):
I gettoni di pre-elaborazione all'interno di una direttiva al preprocessore non sono soggetti a macro espansione se non diversamente specificato.
ESEMPIO A:
#define EMPTY EMPTY # include <file.h>
la sequenza di pre-elaborazione gettoni sulla seconda linea non è una direttiva al preprocessore, perché non inizia con un # all'inizio della fase di traduzione 4, anche se lo farà dopo la macro VUOTO è stato sostituito
Quindi, no, le macro non possono espandersi in una direttiva al preprocessore '#include
'. Tali direttive devono essere presenti all'inizio della fase di traduzione 4 (manipolazione di tali direttive avviene preelaborazione accade). Dal macro espansione si verifica durante la fase 4, le macro non possono causare qualcosa di esistere all'inizio della fase 4.
Mi piacerebbe far notare però, che il seguente ha di lavoro:
#ifdef WIN32
#define PLATFORM_HEADER "platform/windows/platform.h"
#else
#define PLATFORM_HEADER "platform/linux/platform.h"
#include PLATFORM_HEADER
perché lo standard C dice questo (C99, 6.10.2 (4) - inclusione di file di origine):
Una direttiva al preprocessore della forma
# include pp-tokens new-line
(che non corrisponde una delle due forme precedenti) è consentito. il pre-elaborazione token dopo comprendono nella direttiva vengono elaborati come testo normale. (Ogni identificatore attualmente definito come un nome di macro è sostituita dalla sua lista sostituzione di pre-elaborazione gettoni.)
Tutte le direttive del preprocessore vengono interpretati prima dell'inizio macro espansione, quindi no, non si può avere una macro espandersi in una direttiva # include e lo hanno essere interpretato come tale. Invece, sarà interpretato come codice ++ (corretto) C.