Search code examples
c++openmpatomicreference-type

OpenMP atomic on a reference type?


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 and v (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)?


Solution

  • 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.