Подтвердить что ты не робот

Прагма в определении макроса

Есть ли способ вставить утверждение pragma в макрос с другими утверждениями?

Я пытаюсь добиться чего-то вроде:

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

Я в порядке с решениями для повышения (за исключением волны), если таковой существует.

4b9b3361

Ответ 1

Если вы используете c99 или С++ 0x, существует оператор прагмы, используемый как

_Pragma("argument")

что эквивалентно

#pragma argument

за исключением того, что он может использоваться в макросах (см. раздел 6.10.9 стандарта c99, или 16.9 проекта окончательного комитета С++ 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
 ;

Ответ 2

Одна приятная вещь, которую вы можете сделать с _Pragma ( "аргумент" ), использует ее для решения некоторых проблем с компилятором, таких как

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

Ответ 3

Нет, нет портативного способа сделать это. Опять же, нет никаких переносных способов использования #pragma. Из-за этого многие компиляторы 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 как макросы, которые берут параметры, но я не хотел читать документы, чтобы создать слабое определение только для этого примера. Я оставляю это как упражнение для читателя.

Ответ 4

Есть ли способ вставить утверждение pragma в макрос с другими утверждениями?

Нет, вы не можете помещать инструкции препроцессора в инструкции препроцессора. Однако вы могли бы включить его в функцию inline. Тем не менее, это поражает тег C.