ПРАГМА в определении макроса
есть ли способ встроить оператор pragma в макрос с другими операторами?
Я пытаюсь добиться что-то вроде:
#define DEFINE_DELETE_OBJECT(type)
void delete_ ## type_(int handle);
void delete_ ## type(int handle);
#pragma weak delete_ ## type_ = delete_ ## type
Я в порядке с решениями boost (за исключением wave), если они существуют.
4 ответа:
если вы используете c99 или c++0x, есть оператор pragma, используемый как
_Pragma("argument")
что эквивалентно
#pragma argument
за исключением того, что он может использоваться в макросах (см. раздел 6.10.9 стандарта c99 или 16.9 проекта окончательного комитета c++0x)
например,
#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);
на
gcc -E
даетvoid delete_foo_(int handle); void delete_foo(int handle); #pragma weak delete_foo_ = delete_foo ;
одна хорошая вещь, которую вы можете сделать с _Pragma ("аргумент"), это использовать его для решения некоторых проблем компилятора, таких как
#ifdef _MSC_VER #define DUMMY_PRAGMA _Pragma("argument") #else #define DUMMY_PRAGMA _Pragma("alt argument") #endif
нет, нет переносимый способ сделать это. Опять же, нет никаких переносных способов использования #pragma вообще. Из-за этого многие компиляторы C/C++ определяют свои собственные методы для выполнения ПРАГМА-подобных вещей, и они часто могут быть встроены в макросы, но вам нужно другое определение макросов для каждого компилятора. Если вы готовы пойти по этому пути, вы часто заканчиваете тем, что делаете такие вещи:
#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;
В случае, если его не очевидно, что вы хотите определить
Weak_b
иWeak_e
как начало и конец конструкции брекетинга, потому что некоторые компиляторы, такие как GCC, добавляют атрибуты в качестве добавления к сигнатуре типа, а некоторые, например MSC, добавляют его в качестве префикса (или, по крайней мере, это было однажды, прошло много лет с тех пор, как я использовал MSC). Имея брекетинг выступают заказчиками позволяет определить то, что работает всегда, даже если вам придется пройти всю подпись в компилятор построить.конечно, если вы попытаетесь перенести это в компилятор без нужных атрибутов, вы ничего не сможете сделать, но оставьте макросы расширяться до нуля и надеюсь, что ваш код все еще работает. В случае чисто предупреждающих или оптимизирующих прагм это вполне вероятно. В других случаях, не так много.
О, и я подозреваю, что вам действительно нужно определить Weak_b и Weak_e как макросы, которые принимают параметры, но я не хотел читать документы о том, как создать слабое определение только для этого примера. Я оставляю это как упражнение для читателя.