【问题标题】:Preprocessor token pasting in GCC’s _Pragma operator在 GCC 的 _Pragma 运算符中粘贴预处理器标记
【发布时间】:2011-09-30 09:09:59
【问题描述】:

我正在尝试做类似于another question 的事情,即有条件地在我的程序中包含 OpenMP 编译指示。但是,我想更进一步,避免用户每次使用 pragma 时都需要指定 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 运算符中正确粘贴(字符串化)标记?

【问题讨论】:

    标签: c++ gcc c-preprocessor


    【解决方案1】:

    经过多次尝试和错误,事实证明最简单的解决方案有效:

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

    没有它,什么都没有。

    【讨论】:

    • 如果它这么明显,为什么它就像我尝试的第 20 件事? :)
    【解决方案2】:
    #define MAKE_STRING(x)  #x
    #define LIB_PRAGMA_OMP(x) _Pragma(MAKE_STRING(omp x))
    

    如果您愿意,也可以。我更喜欢它,因为它最大限度地减少了这个辅助函数所做的工作量。

    【讨论】:

      猜你喜欢
      • 2011-06-14
      • 2014-06-14
      • 2021-09-20
      • 2015-11-22
      • 2020-11-14
      • 2011-06-07
      • 1970-01-01
      • 1970-01-01
      • 2011-04-28
      相关资源
      最近更新 更多