2010-06-12 19 views
76

¿Hay alguna manera de incrustar la instrucción pragma en macro con otras instrucciones?Pragma en definir macro

que estoy tratando de lograr algo como:

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

estoy bien con las soluciones de refuerzo (a excepción de las olas), si existe.

+5

Podría decirse que no es ni - #pragmas no están definidos por los estándares C o C++. –

+0

El preprocesador es, incluso si el subcomando permitido específica quiere correr no lo es. – Puppy

+0

@DeadMG: hay muchas cosas que son comunes entre C y C++. Mientras preprocesamiento es _mostly_ común, existen grandes diferencias en cómo se especifica procesamiento previo en función de la lengua estándar está siendo utilizado (C89, C99, C++ y C++ 0x FCD). –

Respuesta

94

Si está utilizando C99 o C++ 0x no es el operador pragma, que se utiliza como

_Pragma("argument") 

lo que equivale a

#pragma argument 

excepto que se puede utilizar en las macros (ver sección 6.10.9 de la norma c99, o 16.9 de la C++ 0x último borrador de comité)

Por ejemplo,

#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); 

cuando se ponen en gcc -E da

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

Como un FYI: MSVC tiene el '__pragma()' operador de preprocesador, que por desgracia es ligeramente diferente de C99 de '_Pragma()' operador (C99 de una serie literal, MSVC de toma fichas que no están en una cadena): http://msdn.microsoft.com/en-us/library/d9x1s805.aspx –

+10

@MichaelBurr MSVC siempre tiene que ser diferente, ¿verdad? – Thomas

-3

¿Hay alguna manera de incrustar la instrucción pragma en macro con otras afirmaciones?

No, no puede poner declaraciones de preprocesador en las instrucciones de preprocesador. Sin embargo, podría ponerlo en una función inline. Eso derrota la etiqueta C, sin embargo.

+1

¿De qué serviría ponerlo en una función en línea? Las directivas de preprocesador se procesan antes que cualquier cosa que pueda reconocer una función. –

+2

C99 tiene 'en línea', y la mayoría de las implementaciones principales de C89 tienen alguna variación. –

+0

@Chris Suponiendo que tu comentario fue dirigido a mí, tu punto es, ¿qué? –

0

No, no hay una forma portátil de hacerlo. Por otra parte, no hay formas portátiles de usar #pragma en absoluto. Debido a esto, muchos compiladores C/C++ definen sus propios métodos para hacer cosas parecidas a pragma, y ​​a menudo se pueden incrustar en macros, pero se necesita una definición de macro diferente en cada compilador. Si usted está dispuesto a ir por ese camino, que a menudo terminan haciendo cosas como esta:

#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;  

En caso de que no es obvio que desea definir Weak_b y Weak_e como construcciones de horquillado comenzar-y-finales porque algunos compiladores como GCC agregue los atributos como un apéndice a una firma de tipo, y algunos, como MSC, lo agregan como un prefijo (o al menos lo hizo una vez, han pasado años desde que utilicé MSC). Tener construcciones de horquillado le permite definir algo que siempre funciona, incluso si tiene que pasar la firma de tipo completa a una construcción de compilador.

Por supuesto, si intenta portar esto a un compilador sin los atributos que desea, no hay nada que pueda hacer sino dejar que las macros se expandan a nada y esperar que su código aún se ejecute. En caso de pragmas de advertencia pura o de optimización, es probable. En otros casos, no tanto.

Oh, y sospecho que en realidad necesitaría definir Weak_b y Weak_e como macros que toman los parámetros, pero no estaba dispuesto a leer los documentos sobre cómo crear una definición débil solo para este ejemplo. Lo dejo como un ejercicio para el lector.

4

Una cosa buena que puede hacer con _Pragma ("argumento") es usarlo para resolver ciertos problemas de compilador como

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