What is the reason for allowing also operator-function-id as the operator name for C++?
I mean,+, -, *, &, |, ^, && and || are allowed too, and the reduction clause only allows identifier (which matches identifier in declare reduction) and the earlier mentioned binary operators.
By allowing both the binary operators and operator-function-id, one can have questions whether say:
- Code: Select all
struct S { int i; S (int); S (const S &); };
#pragma omp declare reduction (+ : S : omp_out.i += omp_in.i ) initializer (omp_priv (0))
#pragma omp declare reduction (operator + : S : omp_out.i += omp_in.i) initializer (omp_priv {0})
#pragma omp declare reduction (operator new[] : S : omp_out.i += omp_in.i) initializer (omp_priv = { 0 })
is valid (i.e. whether + and operator + are the same thing or not (if they are the same thing, then that would be redeclaration error, if they are different, how should one choose which of those to use for S s; ... #pragma omp simd reduction (+ : s), and whether it is ok to specify something weird like operator for anything but the binary operators that reduction clause allows).
Also, in the restrictions there is a line that only omp_out and omp_in variables may appear in the combiner expression (and similarly omp_priv and omp_orig in the initializer clause. Does that mean the expression can't refer to any other vars or declare their own vars etc., or just that omp_priv and omp_orig may not be used in the combiner and similarly for the initializer clause?
- Code: Select all
struct T { unsigned char t[16]; };
extern int var;
extern int foo (int &, int &, int), baz (int &, int);
void bar (int &x, int &y)
{
x = (x + y) & var;
}
#pragma omp declare reduction (+ : T : [&]{ int i; for (i = 0; i < 16; i++) omp_out.t[i] += omp_in.t[i]; } ()) initializer (omp_priv = { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } })
#pragma omp declare reduction (q : int : foo (omp_out, omp_in, var)) initializer (baz (omp_priv, var))
#pragma omp declare reduction (q2 : int : bar (omp_out, omp_in))
Are all 3 above invalid because of that? There is a variable (i) in the lambda inside of the expression, so a variable other than omp_out and omp_in appears in the combiner expression.
Or the second declare reduction calls a function referencing a variable other than omp_out and omp_in in the combiner, and calls another function with argument other than omp_priv and omp_orig in the initializer.
Or the third declare reduction call, which, while not using some other variable directly in the expression uses the variable in the function that the expression calls.
Also, is it valid to override the standard built-in reductions?
Say
- Code: Select all
#pragma omp declare reduction (+ : int, float : omp_out *= omp_in)
? Given that 2.14.3.6 says those are implicitly declared, perhaps explicit declaration is supposed to be conflicting with the implicit declaration, rather than override it. As in C++ one can't override operators on arithmetic types either, not allowing this would be logical.