Member initialization for non-copyable variable in C++17Is there a difference between copy initialization and direct initialization?C++11 member initializer list vs in-class initializer?What are the differences between a pointer variable and a reference variable in C++?How to initialize private static members in C++?How to initialize all members of an array to the same value?Initialization of an ArrayList in one lineJavaScript check if variable exists (is defined/initialized)Can I list-initialize a vector of move-only type?initializing a non-copyable member (or other object) in-place from a factory functionWhat are the new features in C++17?container of non-copyable in std::optional
How much of a discount should I seek when prepaying a whole year's rent?
What does "你舒服吗" mean in a relationship context?
Why doesn't knowledge of how magic works break magic in this world?
Is there something as common frequency?
Java 13 Triple-quote Text Block *WITHOUT* newlines
Should I replace fillable PDFs?
What are the downsides of being a debt-free country (no foreign national debt)?
Sudden cheap travel?
Why is 1>a.txt 2>&1 different from 1>a.txt 2>a.txt ? (Example shown)
Fourier transform is an isomorphism...but we don’t get when each frequency appears?
Monthly budget screen - need to take into account whether it's early/late in the month
A Plethora of Puzzled Pawns
Solve unwanted white "waves" and "Pacman squares" in low-light picture - post using Google Photos
Is it appropriate to ask for the text of a eulogy?
How does a religion based around destroying the world attract followers
Is "Are you interviewing other candidates?" a good or terrible response when asked if you are interviewing with other companies?
Why is there a preference to use the cumulative distribution function to characterise a random variable instead of the probability density function?
Should trigger handlers be static or non-static?
Is it Possible to Catch an Unknown Exception?
Early computers without screens or sensors
Any real contribution of functional analysis to quantum theory as a branch of physics?
Story ID: plugging vacuum leak with one's butt
Grandpa really likes these brands
Why is casting a DATE field to VARCHAR datatype non-deterministic and is there a way to make it deterministic?
Member initialization for non-copyable variable in C++17
Is there a difference between copy initialization and direct initialization?C++11 member initializer list vs in-class initializer?What are the differences between a pointer variable and a reference variable in C++?How to initialize private static members in C++?How to initialize all members of an array to the same value?Initialization of an ArrayList in one lineJavaScript check if variable exists (is defined/initialized)Can I list-initialize a vector of move-only type?initializing a non-copyable member (or other object) in-place from a factory functionWhat are the new features in C++17?container of non-copyable in std::optional
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty
margin-bottom:0;
When performing member initialization for non-copyable variable (such as std::atomic<int>
), it's required to use direct-initialization
rather than copy-initialization
according to answer here. However when I turn on -std=c++17
in g++ 7.4.0
, it seems that the latter one also works well.
#include <atomic>
class A
std::atomic<int> a = 0; // copy-initialization
std::atomic<int> b0; // direct-initialization
;
$ g++ -c atomic.cc -std=c++11 // or c++14
atomic.cc:4:26: error: use of deleted function ‘std::atomic<int>::atomic(const std::atomic<int>&)’
std::atomic<int> a = 0; // copy-initialization
$ g++ -c atomic.cc -std=c++17
// no error
It also failed when compiling with g++ 6.5.0
even with -std=c++17
. Which one is correct here?
c++ initialization language-lawyer c++17 copy-elision
add a comment
|
When performing member initialization for non-copyable variable (such as std::atomic<int>
), it's required to use direct-initialization
rather than copy-initialization
according to answer here. However when I turn on -std=c++17
in g++ 7.4.0
, it seems that the latter one also works well.
#include <atomic>
class A
std::atomic<int> a = 0; // copy-initialization
std::atomic<int> b0; // direct-initialization
;
$ g++ -c atomic.cc -std=c++11 // or c++14
atomic.cc:4:26: error: use of deleted function ‘std::atomic<int>::atomic(const std::atomic<int>&)’
std::atomic<int> a = 0; // copy-initialization
$ g++ -c atomic.cc -std=c++17
// no error
It also failed when compiling with g++ 6.5.0
even with -std=c++17
. Which one is correct here?
c++ initialization language-lawyer c++17 copy-elision
1
Possible duplicate ?: stackoverflow.com/questions/1051379/…
– darune
Sep 30 at 9:54
add a comment
|
When performing member initialization for non-copyable variable (such as std::atomic<int>
), it's required to use direct-initialization
rather than copy-initialization
according to answer here. However when I turn on -std=c++17
in g++ 7.4.0
, it seems that the latter one also works well.
#include <atomic>
class A
std::atomic<int> a = 0; // copy-initialization
std::atomic<int> b0; // direct-initialization
;
$ g++ -c atomic.cc -std=c++11 // or c++14
atomic.cc:4:26: error: use of deleted function ‘std::atomic<int>::atomic(const std::atomic<int>&)’
std::atomic<int> a = 0; // copy-initialization
$ g++ -c atomic.cc -std=c++17
// no error
It also failed when compiling with g++ 6.5.0
even with -std=c++17
. Which one is correct here?
c++ initialization language-lawyer c++17 copy-elision
When performing member initialization for non-copyable variable (such as std::atomic<int>
), it's required to use direct-initialization
rather than copy-initialization
according to answer here. However when I turn on -std=c++17
in g++ 7.4.0
, it seems that the latter one also works well.
#include <atomic>
class A
std::atomic<int> a = 0; // copy-initialization
std::atomic<int> b0; // direct-initialization
;
$ g++ -c atomic.cc -std=c++11 // or c++14
atomic.cc:4:26: error: use of deleted function ‘std::atomic<int>::atomic(const std::atomic<int>&)’
std::atomic<int> a = 0; // copy-initialization
$ g++ -c atomic.cc -std=c++17
// no error
It also failed when compiling with g++ 6.5.0
even with -std=c++17
. Which one is correct here?
c++ initialization language-lawyer c++17 copy-elision
c++ initialization language-lawyer c++17 copy-elision
edited Oct 1 at 1:48
songyuanyao
112k13 gold badges214 silver badges296 bronze badges
112k13 gold badges214 silver badges296 bronze badges
asked Sep 30 at 8:44
zingdlezingdle
3172 silver badges9 bronze badges
3172 silver badges9 bronze badges
1
Possible duplicate ?: stackoverflow.com/questions/1051379/…
– darune
Sep 30 at 9:54
add a comment
|
1
Possible duplicate ?: stackoverflow.com/questions/1051379/…
– darune
Sep 30 at 9:54
1
1
Possible duplicate ?: stackoverflow.com/questions/1051379/…
– darune
Sep 30 at 9:54
Possible duplicate ?: stackoverflow.com/questions/1051379/…
– darune
Sep 30 at 9:54
add a comment
|
2 Answers
2
active
oldest
votes
Behavior changed since C++17, which requires compilers to omit the copy/move construction in std::atomic<int> a = 0;
, i.e. guaranteed copy elision.
(emphasis mine)
Under the following circumstances, the compilers are required to omit the copy and move construction of class objects, even if the copy/move constructor and the destructor have observable side-effects. The objects are constructed directly into the storage where they would otherwise be copied/moved to. The copy/move constructors need not be present or accessible, as the language rules ensure that no copy/move operation takes place, even conceptually:
In details, std::atomic<int> a = 0;
performs copy initialization:
If T is a class type, and the cv-unqualified version of the type of other is not T or derived from T, or if T is non-class type, but the type of other is a class type, user-defined conversion sequences that can convert from the type of other to T (or to a type derived from T if T is a class type and a conversion function is available) are examined and the best one is selected through overload resolution. The result of the conversion, which is a
prvalue temporary (until C++17)
prvalue expression (since C++17)
if a converting constructor was used, is then used to direct-initialize the object.
and
(emphasis mine)
if T is a class type and the initializer is a prvalue expression whose cv-unqualified type is the same class as T, the initializer expression itself, rather than a temporary materialized from it, is used to initialize the destination object
That means a
is initialized from 0
directly, there's no temporary to be constructed and then no longer a temporary to copy/move from.
Before C++17, in concept std::atomic<int> a = 0;
requires a temporary std::atomic
to be constructed from 0
, then the temporary is used to copy-construct a
.
Even copy elision is allowed before C++17, it's considered as an optimization:
(emphasis mine)
This is an optimization: even when it takes place and the copy/
move (since C++11)
constructor is not called, it still must be present and accessible (as if no optimization happened at all), otherwise the program is ill-formed:
That's why gcc triggers diagnostic in pre-c++17 mode for std::atomic<int> a = 0;
.
(emphasis mine)
Note: the rule above does not specify an optimization: C++17 core language specification of prvalues and temporaries is fundamentally different from that of the earlier C++ revisions: there is no longer a temporary to copy/move from. Another way to describe C++17 mechanics is "unmaterialized value passing": prvalues are returned and used without ever materializing a temporary.
BTW: I suppose there was a bug in g++ 6.5.0
with -std=c++17
; and it has been fixed in later version.
I think you somehow misunderstood what OP is aksing. OP isn't asking for c++17 vs. pre-c++17.
– darune
Sep 30 at 9:22
1
@darune I think OP's asking why the copy initialization works with-std=c++17
(but not-std=c++11
or-std=c++14
, and I tried to explain why it should work with C++17.
– songyuanyao
Sep 30 at 9:25
Exactly, I think this answer is more right than the other one from @darune (as it stands currently)
– ustulation
Sep 30 at 9:26
2
@MaxLanghof Except for gcc 6.5.0 with-std=c++17
not accepting the code when it should. But only because its C++17 support was still partial and mandatory copy elision not implemented yet.
– walnut
Sep 30 at 9:33
1
Different cpp standard and g++ version cause my confusion here. When asking this question I have no idea that C++17 make this elision mandatory nor old g++ has bug. Thanks for everyone's answers/comments!
– zingdle
Sep 30 at 10:16
|
show 3 more comments
Which one is correct here?
The 7.4.0 is correct. The copy can be elided for this case which is why it is Ok. (although this requires c++17).
(see https://en.cppreference.com/w/cpp/language/copy_initialization for more details)
Isn't the rule something like: Even if it can be elided the behaviour should be as-if there was no elision performed and that should be legit. Then elision happens if the compiler can figure it out. (Sorry I don't have the std at hand just now). So maybe it's not that it's elided but some rule change (around that) for C++17 that has caused it to succeed there ?
– ustulation
Sep 30 at 8:52
@ustulation It's likely just a bug in the earlier version (these types of bugs in c++ implementations are unfortunately somewhat common) - see en.cppreference.com/w/cpp/language/copy_initialization
– darune
Sep 30 at 9:06
See this: en.cppreference.com/w/cpp/language/copy_elision : "This is an optimization: even when it takes place and the copy/move (since C++11) constructor is not called, it still must be present and accessible (as if no optimization happened at all), otherwise the program is ill-formed:"
– ustulation
Sep 30 at 9:18
1
@ustulation that's also stated in the link I provided to copy initialization
– darune
Sep 30 at 9:19
3
@ustulation It is indeed a change in C++17 that makes this well-formed (see the other answer): Instead of being a conceptual copy (or move) of a temporary which could be elided, it is simply initialization now and no temporary is ever materialized (even conceptually).
– Max Langhof
Sep 30 at 9:31
|
show 3 more comments
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/4.0/"u003ecc by-sa 4.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f58164350%2fmember-initialization-for-non-copyable-variable-in-c17%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Behavior changed since C++17, which requires compilers to omit the copy/move construction in std::atomic<int> a = 0;
, i.e. guaranteed copy elision.
(emphasis mine)
Under the following circumstances, the compilers are required to omit the copy and move construction of class objects, even if the copy/move constructor and the destructor have observable side-effects. The objects are constructed directly into the storage where they would otherwise be copied/moved to. The copy/move constructors need not be present or accessible, as the language rules ensure that no copy/move operation takes place, even conceptually:
In details, std::atomic<int> a = 0;
performs copy initialization:
If T is a class type, and the cv-unqualified version of the type of other is not T or derived from T, or if T is non-class type, but the type of other is a class type, user-defined conversion sequences that can convert from the type of other to T (or to a type derived from T if T is a class type and a conversion function is available) are examined and the best one is selected through overload resolution. The result of the conversion, which is a
prvalue temporary (until C++17)
prvalue expression (since C++17)
if a converting constructor was used, is then used to direct-initialize the object.
and
(emphasis mine)
if T is a class type and the initializer is a prvalue expression whose cv-unqualified type is the same class as T, the initializer expression itself, rather than a temporary materialized from it, is used to initialize the destination object
That means a
is initialized from 0
directly, there's no temporary to be constructed and then no longer a temporary to copy/move from.
Before C++17, in concept std::atomic<int> a = 0;
requires a temporary std::atomic
to be constructed from 0
, then the temporary is used to copy-construct a
.
Even copy elision is allowed before C++17, it's considered as an optimization:
(emphasis mine)
This is an optimization: even when it takes place and the copy/
move (since C++11)
constructor is not called, it still must be present and accessible (as if no optimization happened at all), otherwise the program is ill-formed:
That's why gcc triggers diagnostic in pre-c++17 mode for std::atomic<int> a = 0;
.
(emphasis mine)
Note: the rule above does not specify an optimization: C++17 core language specification of prvalues and temporaries is fundamentally different from that of the earlier C++ revisions: there is no longer a temporary to copy/move from. Another way to describe C++17 mechanics is "unmaterialized value passing": prvalues are returned and used without ever materializing a temporary.
BTW: I suppose there was a bug in g++ 6.5.0
with -std=c++17
; and it has been fixed in later version.
I think you somehow misunderstood what OP is aksing. OP isn't asking for c++17 vs. pre-c++17.
– darune
Sep 30 at 9:22
1
@darune I think OP's asking why the copy initialization works with-std=c++17
(but not-std=c++11
or-std=c++14
, and I tried to explain why it should work with C++17.
– songyuanyao
Sep 30 at 9:25
Exactly, I think this answer is more right than the other one from @darune (as it stands currently)
– ustulation
Sep 30 at 9:26
2
@MaxLanghof Except for gcc 6.5.0 with-std=c++17
not accepting the code when it should. But only because its C++17 support was still partial and mandatory copy elision not implemented yet.
– walnut
Sep 30 at 9:33
1
Different cpp standard and g++ version cause my confusion here. When asking this question I have no idea that C++17 make this elision mandatory nor old g++ has bug. Thanks for everyone's answers/comments!
– zingdle
Sep 30 at 10:16
|
show 3 more comments
Behavior changed since C++17, which requires compilers to omit the copy/move construction in std::atomic<int> a = 0;
, i.e. guaranteed copy elision.
(emphasis mine)
Under the following circumstances, the compilers are required to omit the copy and move construction of class objects, even if the copy/move constructor and the destructor have observable side-effects. The objects are constructed directly into the storage where they would otherwise be copied/moved to. The copy/move constructors need not be present or accessible, as the language rules ensure that no copy/move operation takes place, even conceptually:
In details, std::atomic<int> a = 0;
performs copy initialization:
If T is a class type, and the cv-unqualified version of the type of other is not T or derived from T, or if T is non-class type, but the type of other is a class type, user-defined conversion sequences that can convert from the type of other to T (or to a type derived from T if T is a class type and a conversion function is available) are examined and the best one is selected through overload resolution. The result of the conversion, which is a
prvalue temporary (until C++17)
prvalue expression (since C++17)
if a converting constructor was used, is then used to direct-initialize the object.
and
(emphasis mine)
if T is a class type and the initializer is a prvalue expression whose cv-unqualified type is the same class as T, the initializer expression itself, rather than a temporary materialized from it, is used to initialize the destination object
That means a
is initialized from 0
directly, there's no temporary to be constructed and then no longer a temporary to copy/move from.
Before C++17, in concept std::atomic<int> a = 0;
requires a temporary std::atomic
to be constructed from 0
, then the temporary is used to copy-construct a
.
Even copy elision is allowed before C++17, it's considered as an optimization:
(emphasis mine)
This is an optimization: even when it takes place and the copy/
move (since C++11)
constructor is not called, it still must be present and accessible (as if no optimization happened at all), otherwise the program is ill-formed:
That's why gcc triggers diagnostic in pre-c++17 mode for std::atomic<int> a = 0;
.
(emphasis mine)
Note: the rule above does not specify an optimization: C++17 core language specification of prvalues and temporaries is fundamentally different from that of the earlier C++ revisions: there is no longer a temporary to copy/move from. Another way to describe C++17 mechanics is "unmaterialized value passing": prvalues are returned and used without ever materializing a temporary.
BTW: I suppose there was a bug in g++ 6.5.0
with -std=c++17
; and it has been fixed in later version.
I think you somehow misunderstood what OP is aksing. OP isn't asking for c++17 vs. pre-c++17.
– darune
Sep 30 at 9:22
1
@darune I think OP's asking why the copy initialization works with-std=c++17
(but not-std=c++11
or-std=c++14
, and I tried to explain why it should work with C++17.
– songyuanyao
Sep 30 at 9:25
Exactly, I think this answer is more right than the other one from @darune (as it stands currently)
– ustulation
Sep 30 at 9:26
2
@MaxLanghof Except for gcc 6.5.0 with-std=c++17
not accepting the code when it should. But only because its C++17 support was still partial and mandatory copy elision not implemented yet.
– walnut
Sep 30 at 9:33
1
Different cpp standard and g++ version cause my confusion here. When asking this question I have no idea that C++17 make this elision mandatory nor old g++ has bug. Thanks for everyone's answers/comments!
– zingdle
Sep 30 at 10:16
|
show 3 more comments
Behavior changed since C++17, which requires compilers to omit the copy/move construction in std::atomic<int> a = 0;
, i.e. guaranteed copy elision.
(emphasis mine)
Under the following circumstances, the compilers are required to omit the copy and move construction of class objects, even if the copy/move constructor and the destructor have observable side-effects. The objects are constructed directly into the storage where they would otherwise be copied/moved to. The copy/move constructors need not be present or accessible, as the language rules ensure that no copy/move operation takes place, even conceptually:
In details, std::atomic<int> a = 0;
performs copy initialization:
If T is a class type, and the cv-unqualified version of the type of other is not T or derived from T, or if T is non-class type, but the type of other is a class type, user-defined conversion sequences that can convert from the type of other to T (or to a type derived from T if T is a class type and a conversion function is available) are examined and the best one is selected through overload resolution. The result of the conversion, which is a
prvalue temporary (until C++17)
prvalue expression (since C++17)
if a converting constructor was used, is then used to direct-initialize the object.
and
(emphasis mine)
if T is a class type and the initializer is a prvalue expression whose cv-unqualified type is the same class as T, the initializer expression itself, rather than a temporary materialized from it, is used to initialize the destination object
That means a
is initialized from 0
directly, there's no temporary to be constructed and then no longer a temporary to copy/move from.
Before C++17, in concept std::atomic<int> a = 0;
requires a temporary std::atomic
to be constructed from 0
, then the temporary is used to copy-construct a
.
Even copy elision is allowed before C++17, it's considered as an optimization:
(emphasis mine)
This is an optimization: even when it takes place and the copy/
move (since C++11)
constructor is not called, it still must be present and accessible (as if no optimization happened at all), otherwise the program is ill-formed:
That's why gcc triggers diagnostic in pre-c++17 mode for std::atomic<int> a = 0;
.
(emphasis mine)
Note: the rule above does not specify an optimization: C++17 core language specification of prvalues and temporaries is fundamentally different from that of the earlier C++ revisions: there is no longer a temporary to copy/move from. Another way to describe C++17 mechanics is "unmaterialized value passing": prvalues are returned and used without ever materializing a temporary.
BTW: I suppose there was a bug in g++ 6.5.0
with -std=c++17
; and it has been fixed in later version.
Behavior changed since C++17, which requires compilers to omit the copy/move construction in std::atomic<int> a = 0;
, i.e. guaranteed copy elision.
(emphasis mine)
Under the following circumstances, the compilers are required to omit the copy and move construction of class objects, even if the copy/move constructor and the destructor have observable side-effects. The objects are constructed directly into the storage where they would otherwise be copied/moved to. The copy/move constructors need not be present or accessible, as the language rules ensure that no copy/move operation takes place, even conceptually:
In details, std::atomic<int> a = 0;
performs copy initialization:
If T is a class type, and the cv-unqualified version of the type of other is not T or derived from T, or if T is non-class type, but the type of other is a class type, user-defined conversion sequences that can convert from the type of other to T (or to a type derived from T if T is a class type and a conversion function is available) are examined and the best one is selected through overload resolution. The result of the conversion, which is a
prvalue temporary (until C++17)
prvalue expression (since C++17)
if a converting constructor was used, is then used to direct-initialize the object.
and
(emphasis mine)
if T is a class type and the initializer is a prvalue expression whose cv-unqualified type is the same class as T, the initializer expression itself, rather than a temporary materialized from it, is used to initialize the destination object
That means a
is initialized from 0
directly, there's no temporary to be constructed and then no longer a temporary to copy/move from.
Before C++17, in concept std::atomic<int> a = 0;
requires a temporary std::atomic
to be constructed from 0
, then the temporary is used to copy-construct a
.
Even copy elision is allowed before C++17, it's considered as an optimization:
(emphasis mine)
This is an optimization: even when it takes place and the copy/
move (since C++11)
constructor is not called, it still must be present and accessible (as if no optimization happened at all), otherwise the program is ill-formed:
That's why gcc triggers diagnostic in pre-c++17 mode for std::atomic<int> a = 0;
.
(emphasis mine)
Note: the rule above does not specify an optimization: C++17 core language specification of prvalues and temporaries is fundamentally different from that of the earlier C++ revisions: there is no longer a temporary to copy/move from. Another way to describe C++17 mechanics is "unmaterialized value passing": prvalues are returned and used without ever materializing a temporary.
BTW: I suppose there was a bug in g++ 6.5.0
with -std=c++17
; and it has been fixed in later version.
edited Oct 2 at 15:01
answered Sep 30 at 8:49
songyuanyaosongyuanyao
112k13 gold badges214 silver badges296 bronze badges
112k13 gold badges214 silver badges296 bronze badges
I think you somehow misunderstood what OP is aksing. OP isn't asking for c++17 vs. pre-c++17.
– darune
Sep 30 at 9:22
1
@darune I think OP's asking why the copy initialization works with-std=c++17
(but not-std=c++11
or-std=c++14
, and I tried to explain why it should work with C++17.
– songyuanyao
Sep 30 at 9:25
Exactly, I think this answer is more right than the other one from @darune (as it stands currently)
– ustulation
Sep 30 at 9:26
2
@MaxLanghof Except for gcc 6.5.0 with-std=c++17
not accepting the code when it should. But only because its C++17 support was still partial and mandatory copy elision not implemented yet.
– walnut
Sep 30 at 9:33
1
Different cpp standard and g++ version cause my confusion here. When asking this question I have no idea that C++17 make this elision mandatory nor old g++ has bug. Thanks for everyone's answers/comments!
– zingdle
Sep 30 at 10:16
|
show 3 more comments
I think you somehow misunderstood what OP is aksing. OP isn't asking for c++17 vs. pre-c++17.
– darune
Sep 30 at 9:22
1
@darune I think OP's asking why the copy initialization works with-std=c++17
(but not-std=c++11
or-std=c++14
, and I tried to explain why it should work with C++17.
– songyuanyao
Sep 30 at 9:25
Exactly, I think this answer is more right than the other one from @darune (as it stands currently)
– ustulation
Sep 30 at 9:26
2
@MaxLanghof Except for gcc 6.5.0 with-std=c++17
not accepting the code when it should. But only because its C++17 support was still partial and mandatory copy elision not implemented yet.
– walnut
Sep 30 at 9:33
1
Different cpp standard and g++ version cause my confusion here. When asking this question I have no idea that C++17 make this elision mandatory nor old g++ has bug. Thanks for everyone's answers/comments!
– zingdle
Sep 30 at 10:16
I think you somehow misunderstood what OP is aksing. OP isn't asking for c++17 vs. pre-c++17.
– darune
Sep 30 at 9:22
I think you somehow misunderstood what OP is aksing. OP isn't asking for c++17 vs. pre-c++17.
– darune
Sep 30 at 9:22
1
1
@darune I think OP's asking why the copy initialization works with
-std=c++17
(but not -std=c++11
or -std=c++14
, and I tried to explain why it should work with C++17.– songyuanyao
Sep 30 at 9:25
@darune I think OP's asking why the copy initialization works with
-std=c++17
(but not -std=c++11
or -std=c++14
, and I tried to explain why it should work with C++17.– songyuanyao
Sep 30 at 9:25
Exactly, I think this answer is more right than the other one from @darune (as it stands currently)
– ustulation
Sep 30 at 9:26
Exactly, I think this answer is more right than the other one from @darune (as it stands currently)
– ustulation
Sep 30 at 9:26
2
2
@MaxLanghof Except for gcc 6.5.0 with
-std=c++17
not accepting the code when it should. But only because its C++17 support was still partial and mandatory copy elision not implemented yet.– walnut
Sep 30 at 9:33
@MaxLanghof Except for gcc 6.5.0 with
-std=c++17
not accepting the code when it should. But only because its C++17 support was still partial and mandatory copy elision not implemented yet.– walnut
Sep 30 at 9:33
1
1
Different cpp standard and g++ version cause my confusion here. When asking this question I have no idea that C++17 make this elision mandatory nor old g++ has bug. Thanks for everyone's answers/comments!
– zingdle
Sep 30 at 10:16
Different cpp standard and g++ version cause my confusion here. When asking this question I have no idea that C++17 make this elision mandatory nor old g++ has bug. Thanks for everyone's answers/comments!
– zingdle
Sep 30 at 10:16
|
show 3 more comments
Which one is correct here?
The 7.4.0 is correct. The copy can be elided for this case which is why it is Ok. (although this requires c++17).
(see https://en.cppreference.com/w/cpp/language/copy_initialization for more details)
Isn't the rule something like: Even if it can be elided the behaviour should be as-if there was no elision performed and that should be legit. Then elision happens if the compiler can figure it out. (Sorry I don't have the std at hand just now). So maybe it's not that it's elided but some rule change (around that) for C++17 that has caused it to succeed there ?
– ustulation
Sep 30 at 8:52
@ustulation It's likely just a bug in the earlier version (these types of bugs in c++ implementations are unfortunately somewhat common) - see en.cppreference.com/w/cpp/language/copy_initialization
– darune
Sep 30 at 9:06
See this: en.cppreference.com/w/cpp/language/copy_elision : "This is an optimization: even when it takes place and the copy/move (since C++11) constructor is not called, it still must be present and accessible (as if no optimization happened at all), otherwise the program is ill-formed:"
– ustulation
Sep 30 at 9:18
1
@ustulation that's also stated in the link I provided to copy initialization
– darune
Sep 30 at 9:19
3
@ustulation It is indeed a change in C++17 that makes this well-formed (see the other answer): Instead of being a conceptual copy (or move) of a temporary which could be elided, it is simply initialization now and no temporary is ever materialized (even conceptually).
– Max Langhof
Sep 30 at 9:31
|
show 3 more comments
Which one is correct here?
The 7.4.0 is correct. The copy can be elided for this case which is why it is Ok. (although this requires c++17).
(see https://en.cppreference.com/w/cpp/language/copy_initialization for more details)
Isn't the rule something like: Even if it can be elided the behaviour should be as-if there was no elision performed and that should be legit. Then elision happens if the compiler can figure it out. (Sorry I don't have the std at hand just now). So maybe it's not that it's elided but some rule change (around that) for C++17 that has caused it to succeed there ?
– ustulation
Sep 30 at 8:52
@ustulation It's likely just a bug in the earlier version (these types of bugs in c++ implementations are unfortunately somewhat common) - see en.cppreference.com/w/cpp/language/copy_initialization
– darune
Sep 30 at 9:06
See this: en.cppreference.com/w/cpp/language/copy_elision : "This is an optimization: even when it takes place and the copy/move (since C++11) constructor is not called, it still must be present and accessible (as if no optimization happened at all), otherwise the program is ill-formed:"
– ustulation
Sep 30 at 9:18
1
@ustulation that's also stated in the link I provided to copy initialization
– darune
Sep 30 at 9:19
3
@ustulation It is indeed a change in C++17 that makes this well-formed (see the other answer): Instead of being a conceptual copy (or move) of a temporary which could be elided, it is simply initialization now and no temporary is ever materialized (even conceptually).
– Max Langhof
Sep 30 at 9:31
|
show 3 more comments
Which one is correct here?
The 7.4.0 is correct. The copy can be elided for this case which is why it is Ok. (although this requires c++17).
(see https://en.cppreference.com/w/cpp/language/copy_initialization for more details)
Which one is correct here?
The 7.4.0 is correct. The copy can be elided for this case which is why it is Ok. (although this requires c++17).
(see https://en.cppreference.com/w/cpp/language/copy_initialization for more details)
edited Sep 30 at 9:29
answered Sep 30 at 8:49
darunedarune
6,7731 gold badge10 silver badges35 bronze badges
6,7731 gold badge10 silver badges35 bronze badges
Isn't the rule something like: Even if it can be elided the behaviour should be as-if there was no elision performed and that should be legit. Then elision happens if the compiler can figure it out. (Sorry I don't have the std at hand just now). So maybe it's not that it's elided but some rule change (around that) for C++17 that has caused it to succeed there ?
– ustulation
Sep 30 at 8:52
@ustulation It's likely just a bug in the earlier version (these types of bugs in c++ implementations are unfortunately somewhat common) - see en.cppreference.com/w/cpp/language/copy_initialization
– darune
Sep 30 at 9:06
See this: en.cppreference.com/w/cpp/language/copy_elision : "This is an optimization: even when it takes place and the copy/move (since C++11) constructor is not called, it still must be present and accessible (as if no optimization happened at all), otherwise the program is ill-formed:"
– ustulation
Sep 30 at 9:18
1
@ustulation that's also stated in the link I provided to copy initialization
– darune
Sep 30 at 9:19
3
@ustulation It is indeed a change in C++17 that makes this well-formed (see the other answer): Instead of being a conceptual copy (or move) of a temporary which could be elided, it is simply initialization now and no temporary is ever materialized (even conceptually).
– Max Langhof
Sep 30 at 9:31
|
show 3 more comments
Isn't the rule something like: Even if it can be elided the behaviour should be as-if there was no elision performed and that should be legit. Then elision happens if the compiler can figure it out. (Sorry I don't have the std at hand just now). So maybe it's not that it's elided but some rule change (around that) for C++17 that has caused it to succeed there ?
– ustulation
Sep 30 at 8:52
@ustulation It's likely just a bug in the earlier version (these types of bugs in c++ implementations are unfortunately somewhat common) - see en.cppreference.com/w/cpp/language/copy_initialization
– darune
Sep 30 at 9:06
See this: en.cppreference.com/w/cpp/language/copy_elision : "This is an optimization: even when it takes place and the copy/move (since C++11) constructor is not called, it still must be present and accessible (as if no optimization happened at all), otherwise the program is ill-formed:"
– ustulation
Sep 30 at 9:18
1
@ustulation that's also stated in the link I provided to copy initialization
– darune
Sep 30 at 9:19
3
@ustulation It is indeed a change in C++17 that makes this well-formed (see the other answer): Instead of being a conceptual copy (or move) of a temporary which could be elided, it is simply initialization now and no temporary is ever materialized (even conceptually).
– Max Langhof
Sep 30 at 9:31
Isn't the rule something like: Even if it can be elided the behaviour should be as-if there was no elision performed and that should be legit. Then elision happens if the compiler can figure it out. (Sorry I don't have the std at hand just now). So maybe it's not that it's elided but some rule change (around that) for C++17 that has caused it to succeed there ?
– ustulation
Sep 30 at 8:52
Isn't the rule something like: Even if it can be elided the behaviour should be as-if there was no elision performed and that should be legit. Then elision happens if the compiler can figure it out. (Sorry I don't have the std at hand just now). So maybe it's not that it's elided but some rule change (around that) for C++17 that has caused it to succeed there ?
– ustulation
Sep 30 at 8:52
@ustulation It's likely just a bug in the earlier version (these types of bugs in c++ implementations are unfortunately somewhat common) - see en.cppreference.com/w/cpp/language/copy_initialization
– darune
Sep 30 at 9:06
@ustulation It's likely just a bug in the earlier version (these types of bugs in c++ implementations are unfortunately somewhat common) - see en.cppreference.com/w/cpp/language/copy_initialization
– darune
Sep 30 at 9:06
See this: en.cppreference.com/w/cpp/language/copy_elision : "This is an optimization: even when it takes place and the copy/move (since C++11) constructor is not called, it still must be present and accessible (as if no optimization happened at all), otherwise the program is ill-formed:"
– ustulation
Sep 30 at 9:18
See this: en.cppreference.com/w/cpp/language/copy_elision : "This is an optimization: even when it takes place and the copy/move (since C++11) constructor is not called, it still must be present and accessible (as if no optimization happened at all), otherwise the program is ill-formed:"
– ustulation
Sep 30 at 9:18
1
1
@ustulation that's also stated in the link I provided to copy initialization
– darune
Sep 30 at 9:19
@ustulation that's also stated in the link I provided to copy initialization
– darune
Sep 30 at 9:19
3
3
@ustulation It is indeed a change in C++17 that makes this well-formed (see the other answer): Instead of being a conceptual copy (or move) of a temporary which could be elided, it is simply initialization now and no temporary is ever materialized (even conceptually).
– Max Langhof
Sep 30 at 9:31
@ustulation It is indeed a change in C++17 that makes this well-formed (see the other answer): Instead of being a conceptual copy (or move) of a temporary which could be elided, it is simply initialization now and no temporary is ever materialized (even conceptually).
– Max Langhof
Sep 30 at 9:31
|
show 3 more comments
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f58164350%2fmember-initialization-for-non-copyable-variable-in-c17%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
Possible duplicate ?: stackoverflow.com/questions/1051379/…
– darune
Sep 30 at 9:54