You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Creates and returns (by value) a named variable of type Product from createProduct function.
calls the above function to instantiate a variable named created of type Product within
the main function.
The text then shows an output from the code and says that it contradicts the previous statement that the return should result in a call to a copy constructor.
The text then explains NRVO as
The compiler can see through the initialization, deduce that the temp object
is used only to initialize created, and can “compress” the creation steps.
And then shows the output with no-elide-constructors flag applied revealing a copy-construction.
It then tries to explain a mandatory optimization applied since C++17 by saying
Not going into details, it will elide additional copies when there’s an unnamed
temporary object from which we initialize a new entity
then presenting a modified variant of the initial code (which uses a braced list initialization
for the function return statement), giving a link to the Compiler Explorer session with the flag
mentioned above not applied and saying that with this code we will always see the output
only with Product(int, const std::string&) constructor output present.
Then it tries to explain the effect saying
In other words, the temporary from createProduct is skipped and used to initialize the
created object directly.
And concludes with referring to another book of the same author for details.
In my opinion the order of presenting the material, the choice of compiler version in combination
with the no-elide-constructors flag applied are not helpful.
To me the major issue of the section is that the text does not explain right from the start
how many copy-constructions we should expect without any optimizations in place.
It only mentions the temporary object created as a result of the function invocation in its next-to-last
paragraph. It never explicitly says that the first copy constructor is expected to be called to create a temporary
to hold the result of the function return value and the second one to copy-construct variable created within the main function.
And without explicitly saying this the reader is left unaware of what is actually being optimized in
different versions of the code.
In the first part of the section when we talk about NRVO we do not explain which of the two
copy-constructions are eliminated by NRVO and which of them we are undoing by applying
the no-elide-constructors flag. We are lumping these things together by talking about
compiler "compressing" the creation steps.
We mention created variable initialization in
the context of NRVO while the variable is supposed to be instantiated from a temporary
object that keeps the result of the function invocation. And this copy-initialization is optimized
by the mandatory optimization that happens even with the flag applied.
We should have explicitly said which of the two optimization we got rid of by applying the flag.
That by applying the flag we revealed the copy-construction of the temporary for the return
statement which was otherwise optimized out by NRVO.
When we present a new version of the code for createProduct function that uses case #8 from copy-list-initialization initializing
the temporary thus manually (with the code change) removing the first case of copy-initialization
we would otherwise have in the original code we never explain to the reader that we are doing the work
that the optional NRVO did for us previously.
Apparently the new version of the code assumes that some temporary object is created which is
then optimized out by the mandatory optimization we've just described.
But why did we change the code? A temporary that is mandatory-optimized was already present
in the previous version of the code.
And what are we trying to show with the last output in comparison with the previous one?
We already did not see the copy-construction output without the flag applied.
And the Compiler Explorer session linked from the last code example doesn't have the flag applied.
So we applied the flag in the previous example, then changed the code for some unexplained reason,
with unexplained to the reader consequences, removed the flag, got the same output as initially.
What should reader learn from this paragraph or the entire section?
My suggestion for the order / content presented in this section is:
Present the initial code linked to Compiler Explorer session compiled under C++14 with no-elide-constructors applied.
Explain that we would ordinarily have two copy-constructions in our code a) for constructing a temporary object that holds the returned value of the function b) for copy-instantiating the created variable.
Explain the effects of mandatory copy-elision applied since C++17. Tell reader which of the two copy constructions explained in the previous step this optimization eliminates by linking to the session of Compiler Explorer which uses C++17 standard but keeps the no-elide-constructors flag applied.
Explain the effects of NRVO and, again, for which of the two copy-construction it works by now removing the flag and using the same C++17 standard for the linked session of Compiler Explorer.
(Optionally) If we really want to present the case of mandatory copy elision in isolation (using the second variant of the code with braced copy-list initialization in return statement then we should definitely explain readers what we are doing and why.
It would also be helpful to refer user to the output of cppinsights.io code using C++14 standard and showing the
/* NRVO variable */ comment within createProduct function and the second of the two copy/constructions
presented in the cppinsights output as Product created = Product(createProduct());
Hope this helps.
The text was updated successfully, but these errors were encountered:
I think the section can be improved.
It starts with presenting a code that
Product
fromcreateProduct
function.created
of typeProduct
withinthe
main
function.The text then shows an output from the code and says that it contradicts the previous statement that the
return
should result in a call to a copy constructor.The text then explains NRVO as
And then shows the output with
no-elide-constructors
flag applied revealing a copy-construction.It then tries to explain a mandatory optimization applied since C++17 by saying
then presenting a modified variant of the initial code (which uses a braced list initialization
for the function return statement), giving a link to the Compiler Explorer session with the flag
mentioned above not applied and saying that with this code we will always see the output
only with
Product(int, const std::string&)
constructor output present.Then it tries to explain the effect saying
And concludes with referring to another book of the same author for details.
In my opinion the order of presenting the material, the choice of compiler version in combination
with the
no-elide-constructors
flag applied are not helpful.To me the major issue of the section is that the text does not explain right from the start
how many copy-constructions we should expect without any optimizations in place.
It only mentions the temporary object created as a result of the function invocation in its next-to-last
paragraph. It never explicitly says that the first copy constructor is expected to be called to create a temporary
to hold the result of the function return value and the second one to copy-construct variable
created
within themain
function.And without explicitly saying this the reader is left unaware of what is actually being optimized in
different versions of the code.
In the first part of the section when we talk about NRVO we do not explain which of the two
copy-constructions are eliminated by NRVO and which of them we are undoing by applying
the
no-elide-constructors
flag. We are lumping these things together by talking aboutcompiler "compressing" the creation steps.
We mention
created
variable initialization inthe context of
NRVO
while the variable is supposed to be instantiated from a temporaryobject that keeps the result of the function invocation. And this copy-initialization is optimized
by the mandatory optimization that happens even with the flag applied.
We should have explicitly said which of the two optimization we got rid of by applying the flag.
That by applying the flag we revealed the copy-construction of the temporary for the
return
statement which was otherwise optimized out by NRVO.
When we present a new version of the code for
createProduct
function that uses case #8 fromcopy-list-initialization initializing
the temporary thus manually (with the code change) removing the first case of copy-initialization
we would otherwise have in the original code we never explain to the reader that we are doing the work
that the optional NRVO did for us previously.
Apparently the new version of the code assumes that some temporary object is created which is
then optimized out by the mandatory optimization we've just described.
But why did we change the code? A temporary that is mandatory-optimized was already present
in the previous version of the code.
And what are we trying to show with the last output in comparison with the previous one?
We already did not see the copy-construction output without the flag applied.
And the Compiler Explorer session linked from the last code example doesn't have the flag applied.
So we applied the flag in the previous example, then changed the code for some unexplained reason,
with unexplained to the reader consequences, removed the flag, got the same output as initially.
What should reader learn from this paragraph or the entire section?
My suggestion for the order / content presented in this section is:
no-elide-constructors
applied.created
variable.no-elide-constructors
flag applied.return
statement then we should definitely explain readers what we are doing and why.It would also be helpful to refer user to the output of cppinsights.io code using C++14 standard and showing the
/* NRVO variable */ comment within
createProduct
function and the second of the two copy/constructionspresented in the cppinsights output as
Product created = Product(createProduct());
Hope this helps.
The text was updated successfully, but these errors were encountered: