Marco Borgeaud 072e67b8d4
Fix asciidoc w.r.t. C++ (#3519)
"C++" spelled as-is can result in unexpected rendering, such as

    C++20 was released before C++17

renders as

    C20 was released before C17

Make consistent use of `[source,cpp]`.
2023-12-21 15:51:41 +01:00

56 lines
2.3 KiB
Plaintext

== Why is this an issue?
In {cpp}, it usually does not matter how many times you access a variable as long as the variable value is the right one. However, this is not the case when the variable is in a memory region mapped to external hardware. In that case, for instance, several successive reads can yield different values (if the memory is updated by the hardware in-between), and several writes of the same value may be significant (some hardware trigger events each time a memory location is written to).
To specify that every read and write has an impact outside of the abstract machine of the language, access to a variable may be qualified as `volatile`: it will oblige the program to perform all specified reads and writes operations without optimizing anything away.
When a variable appears in a compound expression (for instance, ``a{plus}{plus}`` or `a+=2`), the variable is accessed twice even if it is only named once. The standard was not explicit on this topic up until {cpp}23, but this detail matters for `volatile` variables for which every access to the variable matters.
Consequently, it is usually clearer to rewrite the code so that the variable appears twice, matching the number of accesses that will happen.
Note: In {cpp}20, compound expressions on volatile variables were deprecated. This deprecation was removed in {cpp}23, and the number of accesses was made explicit. The reason for removing the deprecation is that such operations are commonly used in embedded code, especially to access specific variable bits. However, using a function with a dedicated name instead of direct bit manipulation usually leads to code that is easier to read.
== How to fix it
As every access to a `volatile` variable matters, the number of access should be explicitly visible in the code.
=== Code examples
==== Noncompliant code example
[source,cpp]
----
void f1(int volatile* p) {
++(*p); // Noncompliant
}
void f2(volatile int& in) {
in += 2; // Noncompliant
}
void f3(volatile int& in) {
int i = in = 2; // Noncompliant
}
----
==== Compliant solution
[source,cpp]
----
void f1(int volatile* p) {
auto val = *p; // One access to read the register
*p = val + 1; // One access to write to it (and potentially overwrite another change)
}
void f2(volatile int& in) {
auto val = in;
in = val + 2;
}
void f3(volatile int& in) {
in = 2;
int i = in;
}
----