Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Assignment operator behavior #407

Closed
ebikeratwork opened this issue Jul 16, 2021 · 1 comment
Closed

Assignment operator behavior #407

ebikeratwork opened this issue Jul 16, 2021 · 1 comment
Labels
awaiting-followup Waiting for more input enhancement New feature or request

Comments

@ebikeratwork
Copy link

ebikeratwork commented Jul 16, 2021

TIL that:

expression1() = expression2();

is NOT(!) the same as:

expression1().operator=(expression2());

when expression1 and expression2 have side effects.

I am not truly an expert on this, but my current understanding is that:

expression1() = expression2();

has a defined order, see: http://eel.is/c++draft/expr.ass:

The assignment operator (=) and the compound assignment operators all group right-to-left. All require a modifiable lvalue as their left operand; their result is an lvalue referring to the left operand. The result in all cases is a bit-field if the left operand is a bit-field. In all cases, the assignment is sequenced after the value computation of the right and left operands, and before the value computation of the assignment expression. The right operand is sequenced before the left operand. With respect to an indeterminately-sequenced function call, the operation of a compound assignment is a single evaluation.

Important is that the right operand is sequenced before the left operand in case of using an assignment operator.

On the other hand, my current understanding (I may be wrong) is that if you have:

func1().func2(func3());

it is not specified in which order func1() and func3() should evaluate.

This wandbox link shows an example where:

expression1() = expression2()

is executed in a different order than

expression1().operator=(expression2());

It would be great if cppinsights could produce code showing in which order the evaluation occurs in the case of assignments
(because the sequencing is defined in that case). However, to make it more readable, splitting up the assignment into more statements should maybe only be done if there are actually function calls on both sides of the assignments.

@andreasfertig
Copy link
Owner

Hello @ebikeratwork,

that is an interesting feature you're bringing up. Things get indeed interesting if it comes to function calls. C++17 changed several statements making them well defined with a fixed evaluation order. However, some parts are still implementation-defined.

Now a couple of things.
First, in the case where it is implementation-defined the order depends on the compiler. C++ Insights can't do anything there, it will always show what Clang does. Otherwise, I would need to keep track of the other compilers.

Second, the evaluation order, let's says guarantees, changed over time. They probably will again in the future. Clang, as far as I know, doesn't tell me the order. I would need to keep track of the changes in the standard and show them depending on the selected standard. I prefer letting Clang do this tracking.

Third, and most importantly, how would you like to see this being visualized?

Andreas

@andreasfertig andreasfertig added the enhancement New feature or request label Jul 19, 2021
@andreasfertig andreasfertig added the awaiting-followup Waiting for more input label Feb 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
awaiting-followup Waiting for more input enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants