Вставка токена препроцессора в операторе _Pragma в GCC - PullRequest
6 голосов
/ 30 сентября 2011

Я пытаюсь сделать что-то похожее на другой вопрос , а именно условно включить прагмы OpenMP в мою программу.Однако я хочу сделать еще один шаг и избежать того, чтобы пользователю приходилось указывать omp каждый раз, когда они используют прагму.Другими словами, я хочу, чтобы следующий код компилировался:

#include <cstdio>
#include <omp.h>

#ifdef _OPENMP
#   define LIB_PRAGMA_OMP(x) _Pragma("omp " #x)
#else
#   define LIB_PRAGMA_OMP(x)
#endif

int main() {
    LIB_PRAGMA_OMP(parallel) {
        std::printf("Hello from thread %d\n", omp_get_thread_num());
    }
}

К сожалению, это не работает.Компилятор жалуется:

ошибка: _Pragma принимает строковый литерал в скобках

Если я использую следующую форму, она работает, хотя:

#define LIB_PRAGMA_OMP(x) _Pragma(#x)

…

LIB_PRAGMA_OMP(omp parallel) …

Однако я бы очень хотел избежать этой избыточности. Как правильно вставить (строковые) токены в оператор _Pragma?

Ответы [ 2 ]

9 голосов
/ 30 сентября 2011

После долгих проб и ошибок выясняется, что самое простое решение работает:

#ifdef _OPENMP
#   define LIB_PRAGMA_OMP(x)  DO_PRAGMA(omp x)
#   define DO_PRAGMA(x) _Pragma ( #x )
#else
#   define LIB_PRAGMA_OMP(x)
#endif

С -DOPENMP я получаю:

# 12 "test_op.cpp"
#pragma omp parallel
# 12 "test_op.cpp"

И без него ничего.

1 голос
/ 07 мая 2019
#define MAKE_STRING(x)  #x
#define LIB_PRAGMA_OMP(x) _Pragma(MAKE_STRING(omp x))

Также работает, если вы предпочитаете это. Мне нравится это лучше, потому что это минимизирует объем работы, выполняемой этой вспомогательной функцией.

...