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;









16


















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?










share|improve this question






















  • 1





    Possible duplicate ?: stackoverflow.com/questions/1051379/…

    – darune
    Sep 30 at 9:54


















16


















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?










share|improve this question






















  • 1





    Possible duplicate ?: stackoverflow.com/questions/1051379/…

    – darune
    Sep 30 at 9:54














16













16









16


4






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?










share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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













  • 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













2 Answers
2






active

oldest

votes


















16



















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.






share|improve this answer



























  • 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


















3




















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)






share|improve this answer



























  • 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












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
);



);














draft saved

draft discarded
















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









16



















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.






share|improve this answer



























  • 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















16



















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.






share|improve this answer



























  • 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













16















16











16









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.






share|improve this answer
















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.







share|improve this answer















share|improve this answer




share|improve this answer








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

















  • 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













3




















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)






share|improve this answer



























  • 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















3




















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)






share|improve this answer



























  • 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













3















3











3










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)






share|improve this answer

















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)







share|improve this answer















share|improve this answer




share|improve this answer








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

















  • 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


















draft saved

draft discarded















































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.




draft saved


draft discarded














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





















































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









Popular posts from this blog

Tamil (spriik) Luke uk diar | Nawigatjuun

Align equal signs while including text over equalitiesAMS align: left aligned text/math plus multicolumn alignmentMultiple alignmentsAligning equations in multiple placesNumbering and aligning an equation with multiple columnsHow to align one equation with another multline equationUsing \ in environments inside the begintabularxNumber equations and preserving alignment of equal signsHow can I align equations to the left and to the right?Double equation alignment problem within align enviromentAligned within align: Why are they right-aligned?

Where does the image of a data connector as a sharp metal spike originate from?Where does the concept of infected people turning into zombies only after death originate from?Where does the motif of a reanimated human head originate?Where did the notion that Dragons could speak originate?Where does the archetypal image of the 'Grey' alien come from?Where did the suffix '-Man' originate?Where does the notion of being injured or killed by an illusion originate?Where did the term “sophont” originate?Where does the trope of magic spells being driven by advanced technology originate from?Where did the term “the living impaired” originate?