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)?
Basic OpenMP Atomic Operations Use OpenMP atomic operations to allow multiple threads to safely update a shared numeric variable, such as on hardware platforms that support atomic operation use.
atomic regions do not guarantee exclusive access with respect to any accesses outside of atomic regions to the same storage location x even if those accesses occur during a critical or ordered region, while an OpenMP lock is owned by the executing task, or during the execution of a reduction clause.
However, other OpenMP synchronization can ensure the desired exclusive access. For example, a barrier that follows a series of atomic updates to x guarantees that subsequent accesses do not form a race with the atomic accesses. A compliant implementation may enforce exclusive access between atomic regions that update different storage locations.
These 8- and 12-page documents provide a quick reference to OpenMP with section numbers that refer you to where you can find greater detail in the full specification.
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.
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