Date: Mon, 5 Jun 2023 21:42:12 +0200
On 05/06/2023 21.05, Tom Honermann wrote:
> On 6/5/23 1:43 PM, Federico Kircheis via Std-Discussion wrote:
>> Hello, I have a question about following snippet of code
>>
>> ----
>> void bar(volatile int& b){
>> b=42;
>> }
>>
>> void foo()
>> {
>> int a = -1;
>> bar(a);
>> }
>> ----
>>
>> With GCC, clang and MSVC, and optimization enabled, a is set to 42,
>> even if a is not a volatile object, and bar completely inlined inside
>> foo:
>>
>> ----
>> bar(int volatile&):
>> mov DWORD PTR [rdi], 42
>> ret
>> foo():
>> mov DWORD PTR [rsp-4], 42
>> ret
>> ----
>>
>> This surprised me, because as far as I know, the standard mostly talks
>> about glvalues
>>
>> > Accesses through volatile glvalues are evaluated strictly according
>> to the rules of the abstract machine.
>>
>> > Reading an object designated by a volatile glvalue (7.2.1),
>> modifying an object, calling a library I/O function, or calling a
>> function that does any of those operations are all side effects, which
>> are changes in the state of the execution environment.
>>
>> and not about pointers marked as volatile to objects that are not.
>> Thus my understanding was that since a is not volatile, compilers are
>> allowed to optimize the "mov DWORD PTR [rsp-4], 42" away.
>
> In bar(), the expression b yields a glvalue to an object of volatile
> type and inlining doesn't change that.
Oops, my original example was
> On 6/5/23 1:43 PM, Federico Kircheis via Std-Discussion wrote:
>> Hello, I have a question about following snippet of code
>>
>> ----
>> void bar(volatile int& b){
>> b=42;
>> }
>>
>> void foo()
>> {
>> int a = -1;
>> bar(a);
>> }
>> ----
>>
>> With GCC, clang and MSVC, and optimization enabled, a is set to 42,
>> even if a is not a volatile object, and bar completely inlined inside
>> foo:
>>
>> ----
>> bar(int volatile&):
>> mov DWORD PTR [rdi], 42
>> ret
>> foo():
>> mov DWORD PTR [rsp-4], 42
>> ret
>> ----
>>
>> This surprised me, because as far as I know, the standard mostly talks
>> about glvalues
>>
>> > Accesses through volatile glvalues are evaluated strictly according
>> to the rules of the abstract machine.
>>
>> > Reading an object designated by a volatile glvalue (7.2.1),
>> modifying an object, calling a library I/O function, or calling a
>> function that does any of those operations are all side effects, which
>> are changes in the state of the execution environment.
>>
>> and not about pointers marked as volatile to objects that are not.
>> Thus my understanding was that since a is not volatile, compilers are
>> allowed to optimize the "mov DWORD PTR [rsp-4], 42" away.
>
> In bar(), the expression b yields a glvalue to an object of volatile
> type and inlining doesn't change that.
Oops, my original example was
---- void bar(volatile int* b){ *b=42; } void foo() { int a = -1; bar(&a); } ---- then tried with a reference and pasted that. But nothing in your explanation changes, thanks ;) > That being said, since a is a local variable that an implementation can > infer is not associated with memory for which reads or writes have side > effects (other than to change the value of the variable) and since it is > provable that there are no other volatile access expressions that impose > an ordering relationship, I think implementations could elide the write. > That they don't might be a missed optimization (perhaps because, in > general, it might be difficult to prove that the write can be elided or > because there is so little to gain from such elision). > > Tom. >> Is my interpretation incorrect and are those optimizations not >> allowed, or are compilers less aggressive when there are volatile >> pointers, as some code bases/users might "hide" non-volatile objects >> behind pointers to volatile objects to try to avoid some optimization? >> >> (removing volatile from the function signature as bar optimizes foo as >> expected) >> >> Best >> >> Federico For what is worth, even a static_cast seems to hinder optimizations void foo(){ int a = -1; *static_cast<volatile int*>(&a) = 42; }
Received on 2023-06-05 19:42:17