3
template <typename T, std::size_t N>
static T sum(const std::array<T, N>& a)
{
    T result;

    // type of result (T) is not determined when pre-process?
    #pragma omp parallel for reduction(+: result)
    for(int i = 0; i < static_cast<int>(N); i++)
    {
        result += a[i];
    }
    return result;
}

I can compile and run above code with MSVC and gcc. Yes, it's excellent!

But my question is in the code comment; "Because the type of result (T) is not determined while pre-processing '#pragma', how does the compiler validate that the type of result is suited to OpenMP reduction?".

I'm sure it's OK if T=double and NG if T=std::string, but how does the pre-processor know the type of T?

I remember I couldn't compile the above code with some minor c++ compiler a long time ago.

Let me ask which behavior (compilable or uncompilable) is correct in the context of C++/OpenMP specifications.

aokomoriuta
  • 63
  • 1
  • 9

1 Answers1

1

It's unspecified (for OpenMP 3.0 or later) or undefined (for OpenMP 2.5)

reduction is one of data-sharing attribute clauses, and OpenMP Application Program Interface Version 2.5 says:

2.8.3 Data-Sharing Attribute Clauses
---- C/C++ ----
If a variable referenced in a data-sharing attribute clause has a type derived from a template, and there are no other references to that variable in the program, then any behavior related to that variable is undefined.
---- C/C++ ----

OpenMP Application Program Interface Version 3.0 says:

2.9.3 Data-Sharing Attribute Clauses
---- C/C++ ----
If a variable referenced in a data-sharing attribute clause has a type derived from a template, and there are no other references to that variable in the program, then any behavior related to that variable is unspecified.
---- C/C++ ----

yohjp
  • 2,985
  • 3
  • 30
  • 100
  • Does that really apply here? Isn't there an *other reference to that variable in the program* at `result += a[i];`? – Zulan Oct 02 '18 at 07:23