0

I am trying to use OpenMP code in preprocessor directives but I am getting error while compiling the code. I am trying to do something like below.

 #include<stdio.h>
 #include<omp.h>
 #define SUM(_X_)
 sum=0.0                            \
 /*I want to put openmp     
  parallel for directive here       \   
 i.e., #parallel for reduction(+:sum)\
  */                                 \
 for (i = 0 ; i < 10 ; i++)          \  
    sum += _X_[i];              \
int main()
{
   int i=0,x[10];
   float sum=0;
   for(i=0;i<10;i++)
      x[i]=i;
   SUM(x);
}       

Does anyone knows how to achieve this?

Massimiliano
  • 7,842
  • 2
  • 47
  • 62
ajay
  • 31
  • 5
  • Put `#pragma omp parallel for reduction(+:sum)` just before `SUM(x);` –  Jun 20 '13 at 13:33

2 Answers2

2

In C, since C99, you have the _Pragma operator that allows you to place pragmas inside macros, e.g.

#define SUM(_X_)                         \
sum=0.0;                                 \
_Pragma("parallel for reduction(+:sum)") \
for (i = 0 ; i < 10 ; i++)               \
    sum += _X_[i]

BTW, be careful, never place a terminating ; at the end of a macro definition.

Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
  • Woah! That's an even better answer. I had to add a `;` after `sum=0.0` and a backslash after `SUM(_X_)` but otherwise ti works. I wonder if it works in MSVC. I can't test it now. –  Jun 20 '13 at 18:33
  • Yes, it can be done with MSVC as well but a little differently http://stackoverflow.com/questions/4782049/pragma-preprocessor-operator-in-visual-c –  Jun 20 '13 at 19:50
1

The OpenMP 3.1 standard, section 2.1, says that (emphasis mine):

OpenMP directives for C/C++ are specified with the pragma preprocessing directive.

Now, both in C and in C++, you are not allowed to introduce new preprocessor macros during the macro expansion phase, and that's why you get an error.

For instance in the latest C++ standard draft (section 16) you will find the following:

The preprocessing tokens within a preprocessing directive are not subject to macro expansion unless otherwise stated

followed by an example that closely resembles your snippet:

In:

#define EMPTY
EMPTY #include <file.h>

the sequence of preprocessing tokens on the second line is not a preprocessing directive, because it does not begin with a # at the start of translation phase 4, even though it will do so after the macro EMPTY has been replaced.

Anyhow, as correctly stated in other answers, you can obtain the same effect as the one you are seeking using the _Pragma operator since C99 and C++11. An example from section 16.9 of the same C++ standard draft:

#pragma listing on "..\listing.dir"

can also be expressed as:

_Pragma ( "listing on \"..\\listing.dir\"" )

The latter form is processed in the same way whether it appears literally as shown, or results from macro replacement, as in:

#define LISTING(x) PRAGMA(listing on #x)
#define PRAGMA(x) _Pragma(#x)
LISTING( ..\listing.dir )

Finally, pay attention at the choice of your names, as _X_ is potentially a name reserved to the implementation (section 17.6.4.3.2):

Certain sets of names and function signatures are always reserved to the implementation:

  • Each name that contains a double underscore __ or begins with an underscore followed by an uppercase letter (2.12) is reserved to the implementation for any use
  • Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace
Massimiliano
  • 7,842
  • 2
  • 47
  • 62
  • Good explanation. I don't need to read the standard. I can just read your answers. –  Jun 20 '13 at 13:36