Pragma nella definizione macro


99

C'è un modo per incorporare l'istruzione pragma nella macro con altre istruzioni?

Sto cercando di ottenere qualcosa come:

#define DEFINE_DELETE_OBJECT(type)                      \
    void delete_ ## type_(int handle);                  \
    void delete_ ## type(int handle);                                                \
    #pragma weak delete_ ## type_ = delete_ ## type

Sono d'accordo con le soluzioni boost (salvo per wave), se ne esiste una.


5
Probabilmente non è né l'uno né l'altro - #pragmas non sono definiti dagli standard C o C ++.

Il preprocessore lo è, anche se il sottocomando consentito specifico che desidera eseguire non lo è.
Puppy

@DeadMG: ci sono molte cose comuni tra C e C ++. Sebbene la preelaborazione sia per lo più comune, esistono differenze importanti nel modo in cui viene specificata la preelaborazione a seconda dello standard di linguaggio utilizzato (C89, C99, C ++ e C ++ 0x FCD).
James McNellis

2
@ James McNellis: Solo perché tecnicamente, la maggior parte dei programmi C è portabile in C ++, non rende questa funzionalità veramente comune, dal momento che nessun programmatore C ++ lo farebbe per la maggior parte. Le due lingue in realtà non hanno molto in comune.
Cucciolo

Risposte:


115

Se stai usando c99 o c ++ 0x c'è l'operatore pragma, usato come

_Pragma("argument")

che è equivalente a

#pragma argument

tranne che può essere utilizzato nelle macro (vedere la sezione 6.10.9 dello standard c99 o 16.9 della bozza del comitato finale c ++ 0x)

Per esempio,

#define STRINGIFY(a) #a
#define DEFINE_DELETE_OBJECT(type)                      \
    void delete_ ## type ## _(int handle);                  \
    void delete_ ## type(int handle);                   \
    _Pragma( STRINGIFY( weak delete_ ## type ## _ = delete_ ## type) )
DEFINE_DELETE_OBJECT(foo);

quando messo in gcc -E

void delete_foo_(int handle); void delete_foo(int handle);
#pragma weak delete_foo_ = delete_foo
 ;

32
Per tua informazione: MSVC ha l' __pragma()operatore del preprocessore, che purtroppo è leggermente diverso dall'operatore di C99 _Pragma()(C99 prende una stringa letterale, MSVC accetta i token che non sono in una stringa): msdn.microsoft.com/en-us/library/d9x1s805 .aspx
Michael Burr

15
@MichaelBurr MSVC deve sempre essere diverso, non è vero?
Thomas,

5

Una cosa carina che puoi fare con _Pragma ("argomento") è usarlo per affrontare alcuni problemi del compilatore come

#ifdef _MSC_VER
#define DUMMY_PRAGMA _Pragma("argument")
#else
#define DUMMY_PRAGMA _Pragma("alt argument")
#endif

0

No, non esiste un modo portatile per farlo. Inoltre, non ci sono modi portatili per usare #pragma. Per questo motivo, molti compilatori C / C ++ definiscono i propri metodi per fare cose simili a pragma, e spesso possono essere incorporati nelle macro, ma è necessaria una definizione di macro diversa su ogni compilatore. Se sei disposto a seguire quella strada, spesso finisci per fare cose come questa:

#if defined(COMPILER_GCC)
#define Weak_b
#define Weak_e __attribute__((weak))
#elif defined(COMPILER_FOO)
#define Weak_b __Is_Weak
#define Weak_e
#endif

#define DEFINE_DELETE_OBJECT(type)                      \
    Weak_b void delete_ ## type_(int handle) Weak_e;    \
    Weak_b void delete_ ## type(int handle)  Weak_e;    

Nel caso non sia ovvio che si desidera definire Weak_be Weak_ecome costrutti di parentesi di inizio e fine perché alcuni compilatori come GCC aggiungono gli attributi come addendum a una firma di tipo e alcuni, come MSC, lo aggiungono come prefisso (o almeno lo ha fatto una volta, sono passati anni da quando ho usato MSC). Avere i comandi di bracketing ti permette di definire qualcosa che funziona sempre, anche se devi passare l'intera firma del tipo in un costrutto del compilatore.

Ovviamente, se provi a portarlo su un compilatore senza gli attributi che desideri, non puoi fare altro che lasciare che le macro si espandano e sperare che il tuo codice funzioni ancora. In caso di pragmi puramente di avvertimento o ottimizzazione, questo è probabile. In altri casi, non così tanto.

Oh, e sospetto che avresti effettivamente bisogno di definire Weak_b e Weak_e come macro che accettano parametri, ma non ero disposto a leggere i documenti su come creare una definizione debole solo per questo esempio. Lo lascio come esercizio per il lettore.


-3

c'è un modo per incorporare l'istruzione pragma nella macro con altre istruzioni?

No, non è possibile inserire istruzioni del preprocessore nelle istruzioni del preprocessore. Tuttavia, potresti metterlo in una inlinefunzione. Questo però sconfigge il Ctag.


1
A che serve metterlo in una funzione inline? Le direttive del preprocessore vengono elaborate prima di tutto ciò che potrebbe riconoscere una funzione.

2
C99 ha inlinee la maggior parte delle principali implementazioni C89 presenta alcune variazioni.
Chris Lutz,

@ Chris Supponendo che il tuo commento fosse diretto a me - il tuo punto è - cosa?

@ Neil - No, scusa. Lo stavo dirigendo all'ultima frase di @ sbi.
Chris Lutz,

1
@ Chris: Ah, quindi inlineè un'altra cosa che C ha preso in prestito da C ++! :)
sbi
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.