Nell'attuare il mio compilatore C11, sto cercando di capire come esattamente per gestire il _Pragma
parola/operatore. C11 §6.10.9 descrive _Pragma
come operatore, quindi sembra possibile ridefinirlo con macro, ovvero #define _Pragma(x) SOME_OTHER_MACRO(x)
. Inoltre, la dichiarazione #undef _Pragma
non dovrebbe avere alcun effetto (supponendo che non sia anteriore a #define
di _Pragma
). Questo è simile al modo in cui le parole chiave possono essere #define
d, come il vecchio hack VC++ #define for if (0) ; else for
. Tuttavia, poiché l'operatore _Pragma
viene valutato durante la fase di traduzione 3, nella stessa fase dell'esecuzione delle direttive del preprocessore, non è chiaro se si tratti di un'eccezione; lo standard non indica se il suo comportamento non definito utilizza _Pragma
come nome di macro._Pragma e sostituzione di macro
ho fatto alcuni test con GCC utilizzando il seguente codice:
#define PRAGMA _Pragma
PRAGMA("message \"hi\"")
_Pragma ("message \"sup\"")
#undef PRAGMA
#undef _Pragma
//#define _Pragma(x)
_Pragma("message \"hello\"")
compilazione con gcc -std=c11 -pedantic -Wall -Wextra -c
uscite:
tmp.c:2:1: note: #pragma message: hi
PRAGMA("message \"hi\"")
^
tmp.c:4:1: note: #pragma message: sup
_Pragma ("message \"sup\"")
^
tmp.c:8:8: warning: undefining "_Pragma" [enabled by default]
#undef _Pragma
^
tmp.c:10:9: error: expected declaration specifiers or ‘...’ before string constant
_Pragma("message \"hello\"")
^
Se aggiungo la linea #undef _Alignof
, GCC non si lamenta a questo proposito.
Ciò suggerisce che GCC implementa _Pragma
tramite una macro (tramite il messaggio di avviso), e che indefiniti si traduce in un errore di compilazione. Se taccio il commento a #define _Pragma(x)
, l'errore scompare (quando la stringa letterale scompare).
Quindi, le mie domande sono:
- sono implementazioni permesso di definire
_Pragma
come solo un macro, e non implementarlo come un operatore? - In caso contrario, GCC ha torto nel farlo?
- se
_Pragma
si doveva essere un operatore, è un comportamento indefinito di definire_Pragma
come macro? - Esiste un ordine tra la valutazione
_Pragma
e altre direttive del preprocessore? O hanno la stessa "precedenza" (cioè sono valutati in ordine)?
Ancora una volta, guardando attraverso lo standard C11 non menziona nulla _Pragma
diverso da quello che è un operatore che può essere utilizzato per #pragma
direttive.
anticipare alcune sostanziale livello di opinione giocherà un rotolo nelle risposte si arriva a questa domanda, (come il void main (void ')' discussioni), tuttavia, la vostra ricerca è evidente, e la vostra le domande sono ben presentate Dovrebbe portare a risposte interessanti.(+1) – ryyker
Non sono sicuro, se capisco correttamente lo standard qui, ma penso, si applica C11 7.1.3 p3: "Se il programma rimuove (con #undef) qualsiasi definizione di macro di un identificatore nel primo gruppo elencato sopra, il comportamento non è definito. "dove il" primo gruppo "menzionato sono identificatori che iniziano con un trattino basso seguito da un altro carattere di sottolineatura o da una lettera maiuscola. – mafso
@mafso che sembra applicarsi solo se c'è una definizione di macro, in primo luogo, in modo da codice come '#ifndef _Pragma #undef _Pragma # endif' non sarebbe invocare UB –