I’m trying to do something similar to another question, namely, conditionally include OpenMP pragmas in my program. However, I want to go one step further and avoid that the user needs to specify omp
every time they use the pragma. In other words, I want the following code to compile:
#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());
}
}
Unfortunately, this doesn’t work. The compiler complains:
error:
_Pragma
takes a parenthesized string literal
If I use the following form, it works, though:
#define LIB_PRAGMA_OMP(x) _Pragma(#x)
…
LIB_PRAGMA_OMP(omp parallel) …
However, I’d really like to avoid this redundancy. How can I paste the (stringified) tokens correctly inside the _Pragma
operator?
The Token Pasting operator is a preprocessor operator. It sends commands to compiler to add or concatenate two tokens into one string. We use this operator at the macro definition.
The double-number-sign or token-pasting operator (##), which is sometimes called the merging or combining operator, is used in both object-like and function-like macros. It permits separate tokens to be joined into a single token, and therefore, can't be the first or last token in the macro definition.
## is called token concatenation, used to concatenate two tokens in a macro invocation.
This is called token pasting or token concatenation. The '##' pre-processing operator performs token pasting. When a macro is expanded, the two tokens on either side of each '##' operator are combined into a single token, which then replaces the '##' and the two original tokens in the macro expansion.
After much trial and error, it turns out that the simplest solution works:
#ifdef _OPENMP
# define LIB_PRAGMA_OMP(x) DO_PRAGMA(omp x)
# define DO_PRAGMA(x) _Pragma ( #x )
#else
# define LIB_PRAGMA_OMP(x)
#endif
With -DOPENMP
, I get:
# 12 "test_op.cpp"
#pragma omp parallel
# 12 "test_op.cpp"
And without it, nothing.
#define MAKE_STRING(x) #x
#define LIB_PRAGMA_OMP(x) _Pragma(MAKE_STRING(omp x))
Also works, if you prefer that. I like it better because it minimizes the amount of work this helper function does.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With