Why is “volatileQualifiedExpr + volatileQualifiedE

2019-04-04 23:35发布

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?

1条回答
劳资没心,怎么记你
2楼-- · 2019-04-04 23:54

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.

查看更多
登录 后发表回答