The OpenMP standard (<= 4.0) says about atomic
:
#pragma omp atomic [read | write | update | capture ] new-line
expression-stmt
where
expression-stmt
is an expression statement with one of the following forms:
...
If clause is update or not present:
x++;
...
In the preceding expressions:
x
andv
(as applicable) are both l-value expressions with scalar type.
...
So, when I interpret this correctly, the following short code snippet is illegal:
int main()
{
int myCounter = 0;
int& reference = myCounter;
#pragma omp parallel for
for (int i = 0; i < 100; ++i)
{
#pragma omp atomic
reference++; // Increment through reference.
}
return 0;
}
Reason: According to this post, a reference (here int& reference
) is not a scalar type. But the standard explicitly states that it must be one, in order to use atomic
.
The code compiles with g++, without any warning (-Wall -Wextra
).
My question is: Have I misunderstood the standard, or the concept of C++'s "reference type"? Or do most compilers compile this code, because otherwise the use of atomic
is severely limited (basically no data on the heap could be the target of atomic
, because you always need a reference or a dereferenced pointer)?
A reference type is not a scalar type. However, this fact has no bearing on your question. The important fact is that an expression that evaluates a reference to a scalar type is an lvalue with scalar type. To be specific, the variable reference
has type int&
but the expression reference
has type int
and value category lvalue. So yes, your program is conforming.