Reputation: 1395
I went through the code below on a C++ quiz site. It also provides an explanation. I am aware that volatile
qualifier signals to the compiler that the value of the variable may be changed by some other factors. The explanation by the site adds that accessing volatile
should be sequenced. Why and how it should be sequenced?
I don't understand what they mean by unsequenced side-effects and scalar object. Please also make it clear.
#include <iostream>
volatile int a;
int main() {
std::cout << (a + a);
}
The issue here is not the missing initializer of the variable
a
- it will implicitly be initialized to 0 here. But the issue is the access to a twice without sequencing between the accesses. According to §1.9¶12, accesses ofvolatile
glvalues are side-effects and according to §1.9¶15 these two unsequenced side-effects on the same scalar object result in undefined behavior.
Upvotes: 3
Views: 384
Reputation: 118352
It is not defined which one of the two accesses occurs first, here.
In this case of a symmetric addition operation it does not matter.
But consider a different operation that's not symmetric:
std::cout << a * (a+1);
Now, consider a volatile
object that, due to external factors, gets automatically incremented after every access. Let's say that, for example, a
is some kind of a hardware register. As I said, let's say that every time it's accessed it gets incremented, so the hardware register contains the value 4 on the first access, and 5 on the second access. A simple counter.
Then, if the first access was for the left hand side of the multiplication, and the second access was for the addition operation on the right hand access of the multiplication, then this becomes
std::cout << 4 * (5+1);
But if the first access was for the right hand side, and the second access was for the left hand side, this becomes
std::cout << 5 * (4+1);
That's why having volatile
objects is not enough. The operations must be sequenced.
Upvotes: 6