When I today read the C Standard, it says about side effects
Accessing a volatile object, modifying an object, modifying a file, or calling a function that does any of those operations are all side effects
and the C++ Standard says
Accessing an object designated by a volatile glvalue (3.10), modifying an object, calling a library I/O function, or calling a function that does any of those operations are all side effects
Hence because both forbid unsequenced side effects to occur on the same scalar object, C allows the following, but C++ makes it undefined behavior
int a = 0;
volatile int *pa = &a;
int b = *pa + *pa;
Am I reading the specifications correctly? And what is the reason for the discrepancy, if so?
I don't believe there is an effective variation between C and C++ in this regards. Though the wording on sequencing varies the end result is the same: both result in undefined behaviour (though C seems to indicate the evaluation will suceed but with an undefined result).
In C99 (sorry, don't have C11 handy) paragraph 5.1.2.3.5 specifies:
— At sequence points, volatile objects are stable in the sense that previous accesses are complete and subsequent accesses have not yet occurred.
Combined with your quote from 5.1.2.3.2 would indicate the value of pa
would not be in a stable state for at least one of the accesses to pa
. This makes logical sense since the compiler would be allowed to evaluate them in any order, just once, or at the same time (if possible). It doesn't actually define what stable means however.
In C++11 there is explicit reference to unsequenced oeprations at 1.9.13. Then point 15 indicates such unsequenced operations on the same operand is undefined. Since undefined behaviour can mean anything happens it is perhaps strong than C's unstable behaviour. However, in both cases there is no guaranteed result of your expression.
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