Incrementing a volatile in C++20 with operations on volatile being deprecated

Viewed 724

C++20 deprecated some certain operations on volatile types (following P1152).

The following code, that was valid prior to C++20:

void busyLoop(std::size_t count) {
  for (volatile size_t counter = 0; counter < count; ++counter);
}

now generates a deprecation warning:

warning: '++' expression of 'volatile'-qualified type is deprecated [-Wvolatile]

Changing the ++ to += or to counter = counter + 1 doesn't help, as the problem seems to be with calculating a new value based on a volatile type.

How can the above code be adjusted to the new C++20 rules?

3 Answers

The point of deprecating these operations is to make it clear that volatile variables are not atomic in any way and should not be expected to be manipulated atomically. Therefore, for any actual code using volatile, you need to read the value into a local, manipulate that local copy, and then write the value back to the volatile value.

This access pattern is designed to mimic what the committee hopes to codify into a function-based interface that would (maybe?) replace volatile entirely at some point. That is, volatile becomes a way you access a memory address at load and store times; it wouldn't be an intrinsic property of an object.

While incrementing the volatile as seen in the question, is deprecated in C++20, you can increment a non-volatile type and assign the result back to the volatile type.

The following code is valid in C++20:

void busyLoop(size_t count) {
  size_t i = 0;
  for ([[maybe_unused]]volatile size_t counter = 0; i < count; counter = i, ++i);
}

counter=counter+1 is correct (to the extent that this code is desirable at all). The warning for it is a GCC bug: it’s supposed to warn only for things like reg=vol=1; which might or might not assign 1 to reg. (Even writing void(counter=counter+1) doesn’t help.)

Related