c-preprocessor pragma stringification

c preprocessor - Pragma en definir macro



c-preprocessor stringification (4)

¿Hay alguna forma de incrustar pragma declaración en macro con otras declaraciones?

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 de acuerdo con las soluciones de impulso (salvo para la ola), si existe.


¿Hay alguna forma de incrustar pragma declaración en macro con otras declaraciones?

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


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 estás dispuesto a seguir ese camino, a menudo terminas 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 sea obvio, usted quiere definir Weak_b y Weak_e como construcciones de horquillado Weak_e y final porque algunos compiladores como GCC agregan 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.

Ah, y sospecho que realmente necesitaría definir Weak_b y Weak_e como macros que toman 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.


Si usa c99 o c ++ 0x, existe el operador pragma, que se usa

_Pragma("argument")

que es equivalente a

#pragma argument

excepto que se puede usar en macros (ver sección 6.10.9 del estándar c99, o 16.9 del borrador final del comité c ++ 0x)

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 pone en gcc -E da

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


Una buena cosa que puedes hacer con _Pragma ("argumento") es utilizarlo para tratar algunos problemas del compilador, como

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