C++ zero initialization - Why is `b` in this program uninitialized, but `a` is initialized?












50















According to the accepted (and only) answer for this Stack Overflow question,




Defining the constructor with



MyTest() = default;


will instead zero-initialize the object.




Then why does the following,



#include <iostream>

struct foo {
foo() = default;
int a;
};

struct bar {
bar();
int b;
};

bar::bar() = default;

int main() {
foo a{};
bar b{};
std::cout << a.a << ' ' << b.b;
}


produce this output:



0 32766


Both constructors defined are default? Right? And for POD types, the default initialization is zero-initialization.



And according to the accepted answer for this question,





  1. If a POD member is not initialized in the constructor nor via C++11
    in-class initialization, it is default-initialized.


  2. The answer is the same regardless of stack or heap.


  3. In C++98 (and not afterward), new int() was specified as performing
    zero initialization.





Despite trying to wrap my (albeit tiny) head around default constructors and default initialization, I couldn't come up with an explanation.










share|improve this question




















  • 3





    Interestingly, I even get a warning for b: main.cpp:18:34: warning: 'b.bar::b' is used uninitialized in this function [-Wuninitialized] coliru.stacked-crooked.com/a/d1b08a4d6fb4ca7e

    – tkausl
    11 hours ago






  • 1





    @TheQuantumPhysicist, for that I ran the program maybe 5~6 times before posting and about 10 times now, a is always zero. b changes around a little.

    – Joey Mallone
    11 hours ago






  • 5





    bar's constructor is user provided whereas foo's constructor is the defaulted one.

    – Jarod42
    11 hours ago








  • 2





    @PeteBecker, I understand that. How could I somehow shake my RAM a little so that if there was zero there, it should now be something else. ;) p.s. I ran the program a dozen times. It is not a big program. You could run it and test it on your system. a is zero. b is not. Seems a is initialized.

    – Joey Mallone
    11 hours ago








  • 1





    @JoeyMallone Regarding "how is it user-provided": There is no guarantee that the definition of bar::bar() is visible in main() - it might be defined in a separate compilation unit and do something very non-trivial while in main() only the declaration is visible. I think you'll agree that this behavior shouldn't change depending on whether you place bar::bar()'s definition in a separate compilation unit or not (even if the whole situation is unintuitive).

    – Max Langhof
    11 hours ago


















50















According to the accepted (and only) answer for this Stack Overflow question,




Defining the constructor with



MyTest() = default;


will instead zero-initialize the object.




Then why does the following,



#include <iostream>

struct foo {
foo() = default;
int a;
};

struct bar {
bar();
int b;
};

bar::bar() = default;

int main() {
foo a{};
bar b{};
std::cout << a.a << ' ' << b.b;
}


produce this output:



0 32766


Both constructors defined are default? Right? And for POD types, the default initialization is zero-initialization.



And according to the accepted answer for this question,





  1. If a POD member is not initialized in the constructor nor via C++11
    in-class initialization, it is default-initialized.


  2. The answer is the same regardless of stack or heap.


  3. In C++98 (and not afterward), new int() was specified as performing
    zero initialization.





Despite trying to wrap my (albeit tiny) head around default constructors and default initialization, I couldn't come up with an explanation.










share|improve this question




















  • 3





    Interestingly, I even get a warning for b: main.cpp:18:34: warning: 'b.bar::b' is used uninitialized in this function [-Wuninitialized] coliru.stacked-crooked.com/a/d1b08a4d6fb4ca7e

    – tkausl
    11 hours ago






  • 1





    @TheQuantumPhysicist, for that I ran the program maybe 5~6 times before posting and about 10 times now, a is always zero. b changes around a little.

    – Joey Mallone
    11 hours ago






  • 5





    bar's constructor is user provided whereas foo's constructor is the defaulted one.

    – Jarod42
    11 hours ago








  • 2





    @PeteBecker, I understand that. How could I somehow shake my RAM a little so that if there was zero there, it should now be something else. ;) p.s. I ran the program a dozen times. It is not a big program. You could run it and test it on your system. a is zero. b is not. Seems a is initialized.

    – Joey Mallone
    11 hours ago








  • 1





    @JoeyMallone Regarding "how is it user-provided": There is no guarantee that the definition of bar::bar() is visible in main() - it might be defined in a separate compilation unit and do something very non-trivial while in main() only the declaration is visible. I think you'll agree that this behavior shouldn't change depending on whether you place bar::bar()'s definition in a separate compilation unit or not (even if the whole situation is unintuitive).

    – Max Langhof
    11 hours ago
















50












50








50


6






According to the accepted (and only) answer for this Stack Overflow question,




Defining the constructor with



MyTest() = default;


will instead zero-initialize the object.




Then why does the following,



#include <iostream>

struct foo {
foo() = default;
int a;
};

struct bar {
bar();
int b;
};

bar::bar() = default;

int main() {
foo a{};
bar b{};
std::cout << a.a << ' ' << b.b;
}


produce this output:



0 32766


Both constructors defined are default? Right? And for POD types, the default initialization is zero-initialization.



And according to the accepted answer for this question,





  1. If a POD member is not initialized in the constructor nor via C++11
    in-class initialization, it is default-initialized.


  2. The answer is the same regardless of stack or heap.


  3. In C++98 (and not afterward), new int() was specified as performing
    zero initialization.





Despite trying to wrap my (albeit tiny) head around default constructors and default initialization, I couldn't come up with an explanation.










share|improve this question
















According to the accepted (and only) answer for this Stack Overflow question,




Defining the constructor with



MyTest() = default;


will instead zero-initialize the object.




Then why does the following,



#include <iostream>

struct foo {
foo() = default;
int a;
};

struct bar {
bar();
int b;
};

bar::bar() = default;

int main() {
foo a{};
bar b{};
std::cout << a.a << ' ' << b.b;
}


produce this output:



0 32766


Both constructors defined are default? Right? And for POD types, the default initialization is zero-initialization.



And according to the accepted answer for this question,





  1. If a POD member is not initialized in the constructor nor via C++11
    in-class initialization, it is default-initialized.


  2. The answer is the same regardless of stack or heap.


  3. In C++98 (and not afterward), new int() was specified as performing
    zero initialization.





Despite trying to wrap my (albeit tiny) head around default constructors and default initialization, I couldn't come up with an explanation.







c++ initialization language-lawyer






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 3 hours ago









Boann

36.8k1289121




36.8k1289121










asked 11 hours ago









Joey MalloneJoey Mallone

1,32721326




1,32721326








  • 3





    Interestingly, I even get a warning for b: main.cpp:18:34: warning: 'b.bar::b' is used uninitialized in this function [-Wuninitialized] coliru.stacked-crooked.com/a/d1b08a4d6fb4ca7e

    – tkausl
    11 hours ago






  • 1





    @TheQuantumPhysicist, for that I ran the program maybe 5~6 times before posting and about 10 times now, a is always zero. b changes around a little.

    – Joey Mallone
    11 hours ago






  • 5





    bar's constructor is user provided whereas foo's constructor is the defaulted one.

    – Jarod42
    11 hours ago








  • 2





    @PeteBecker, I understand that. How could I somehow shake my RAM a little so that if there was zero there, it should now be something else. ;) p.s. I ran the program a dozen times. It is not a big program. You could run it and test it on your system. a is zero. b is not. Seems a is initialized.

    – Joey Mallone
    11 hours ago








  • 1





    @JoeyMallone Regarding "how is it user-provided": There is no guarantee that the definition of bar::bar() is visible in main() - it might be defined in a separate compilation unit and do something very non-trivial while in main() only the declaration is visible. I think you'll agree that this behavior shouldn't change depending on whether you place bar::bar()'s definition in a separate compilation unit or not (even if the whole situation is unintuitive).

    – Max Langhof
    11 hours ago
















  • 3





    Interestingly, I even get a warning for b: main.cpp:18:34: warning: 'b.bar::b' is used uninitialized in this function [-Wuninitialized] coliru.stacked-crooked.com/a/d1b08a4d6fb4ca7e

    – tkausl
    11 hours ago






  • 1





    @TheQuantumPhysicist, for that I ran the program maybe 5~6 times before posting and about 10 times now, a is always zero. b changes around a little.

    – Joey Mallone
    11 hours ago






  • 5





    bar's constructor is user provided whereas foo's constructor is the defaulted one.

    – Jarod42
    11 hours ago








  • 2





    @PeteBecker, I understand that. How could I somehow shake my RAM a little so that if there was zero there, it should now be something else. ;) p.s. I ran the program a dozen times. It is not a big program. You could run it and test it on your system. a is zero. b is not. Seems a is initialized.

    – Joey Mallone
    11 hours ago








  • 1





    @JoeyMallone Regarding "how is it user-provided": There is no guarantee that the definition of bar::bar() is visible in main() - it might be defined in a separate compilation unit and do something very non-trivial while in main() only the declaration is visible. I think you'll agree that this behavior shouldn't change depending on whether you place bar::bar()'s definition in a separate compilation unit or not (even if the whole situation is unintuitive).

    – Max Langhof
    11 hours ago










3




3





Interestingly, I even get a warning for b: main.cpp:18:34: warning: 'b.bar::b' is used uninitialized in this function [-Wuninitialized] coliru.stacked-crooked.com/a/d1b08a4d6fb4ca7e

– tkausl
11 hours ago





Interestingly, I even get a warning for b: main.cpp:18:34: warning: 'b.bar::b' is used uninitialized in this function [-Wuninitialized] coliru.stacked-crooked.com/a/d1b08a4d6fb4ca7e

– tkausl
11 hours ago




1




1





@TheQuantumPhysicist, for that I ran the program maybe 5~6 times before posting and about 10 times now, a is always zero. b changes around a little.

– Joey Mallone
11 hours ago





@TheQuantumPhysicist, for that I ran the program maybe 5~6 times before posting and about 10 times now, a is always zero. b changes around a little.

– Joey Mallone
11 hours ago




5




5





bar's constructor is user provided whereas foo's constructor is the defaulted one.

– Jarod42
11 hours ago







bar's constructor is user provided whereas foo's constructor is the defaulted one.

– Jarod42
11 hours ago






2




2





@PeteBecker, I understand that. How could I somehow shake my RAM a little so that if there was zero there, it should now be something else. ;) p.s. I ran the program a dozen times. It is not a big program. You could run it and test it on your system. a is zero. b is not. Seems a is initialized.

– Joey Mallone
11 hours ago







@PeteBecker, I understand that. How could I somehow shake my RAM a little so that if there was zero there, it should now be something else. ;) p.s. I ran the program a dozen times. It is not a big program. You could run it and test it on your system. a is zero. b is not. Seems a is initialized.

– Joey Mallone
11 hours ago






1




1





@JoeyMallone Regarding "how is it user-provided": There is no guarantee that the definition of bar::bar() is visible in main() - it might be defined in a separate compilation unit and do something very non-trivial while in main() only the declaration is visible. I think you'll agree that this behavior shouldn't change depending on whether you place bar::bar()'s definition in a separate compilation unit or not (even if the whole situation is unintuitive).

– Max Langhof
11 hours ago







@JoeyMallone Regarding "how is it user-provided": There is no guarantee that the definition of bar::bar() is visible in main() - it might be defined in a separate compilation unit and do something very non-trivial while in main() only the declaration is visible. I think you'll agree that this behavior shouldn't change depending on whether you place bar::bar()'s definition in a separate compilation unit or not (even if the whole situation is unintuitive).

– Max Langhof
11 hours ago














3 Answers
3






active

oldest

votes


















43














The issue here is pretty subtle. You would think that



bar::bar() = default;


would give you a compiler generated default constructor, and it does, but it is now considered user provided. [dcl.fct.def.default]/5 states:




Explicitly-defaulted functions and implicitly-declared functions are collectively called defaulted functions, and the implementation shall provide implicit definitions for them ([class.ctor] [class.dtor], [class.copy.ctor], [class.copy.assign]), which might mean defining them as deleted. A function is user-provided if it is user-declared and not explicitly defaulted or deleted on its first declaration. A user-provided explicitly-defaulted function (i.e., explicitly defaulted after its first declaration) is defined at the point where it is explicitly defaulted; if such a function is implicitly defined as deleted, the program is ill-formed. [ Note: Declaring a function as defaulted after its first declaration can provide efficient execution and concise definition while enabling a stable binary interface to an evolving code base. — end note ]




emphasis mine



So we can see that since you did not default bar() when you first declared it, it is now considered user provided. Because of that [dcl.init]/8.2




if T is a (possibly cv-qualified) class type without a user-provided or deleted default constructor, then the object is zero-initialized and the semantic constraints for default-initialization are checked, and if T has a non-trivial default constructor, the object is default-initialized;




no longer applies and we are not value initializing b but instead default initializing it per [dcl.init]/8.1




if T is a (possibly cv-qualified) class type ([class]) with either no default constructor ([class.default.ctor]) or a default constructor that is user-provided or deleted, then the object is default-initialized;







share|improve this answer





















  • 16





    I mean (*_*) .... If to even use the basic constructs of the language, I need to read the fine print of the language draft, then Hallelujah! But it probably seems to be what you say.

    – Joey Mallone
    11 hours ago






  • 5





    @balki Yes, doing bar::bar() = default out of line is the same as doing bar::bar(){} inline.

    – NathanOliver
    11 hours ago






  • 5





    @JoeyMallone Yeah, C++ can be pretty complicated. I'm not sure what the reason for this is.

    – NathanOliver
    11 hours ago






  • 3





    If there is a previous declaration, then a subsequent definition with the default keyword will NOT zero initialize the members. Right? This is correct. It is what is happening here.

    – NathanOliver
    10 hours ago






  • 3





    The reason is right there in your quote: the point of an out-of-line default is to "provide efficient execution and concise definition while enabling a stable binary interface to an evolving code base", in other words, enable you to switch to a user-written body later if necessary without breaking ABI. Note that the out-of-line definition is not implicitly inline and so can only appear in one TU by default; another TU seeing the class definition alone has no way to know if it's explicitly defined as defaulted.

    – T.C.
    6 hours ago





















9














The difference in behaviour comes from the fact that, according to [dcl.fct.def.default]/5, bar::bar is user-provided where foo::foo is not1. As a consequence, foo::foo will value-initialize its members (meaning: zero-initialize foo::a) but bar::bar will stay uninitialized2.





1)[dcl.fct.def.default]/5




A function is user-provided if it is user-declared and not explicitly defaulted or deleted on its first declaration.




2)




From [dcl.init#6]:




To value-initialize an object of type T means:




  • if T is a (possibly cv-qualified) class type with either no default constructor ([class.ctor]) or a default constructor that is user-provided or deleted, then the object is default-initialized;


  • if T is a (possibly cv-qualified) class type without a user-provided or deleted default constructor, then the object is zero-initialized and the semantic constraints for default-initialization are checked, and if T has a non-trivial default constructor, the object is default-initialized;


  • ...





From [dcl.init.list]:




List-initialization of an object or reference of type T is defined as follows:




  • ...


  • Otherwise, if the initializer list has no elements and T is a class type with a default constructor, the object is value-initialized.






From Vittorio Romeo's answer






share|improve this answer

































    3














    From cppreference:




    Aggregate initialization initializes aggregates. It is a form of list-initialization.



    An aggregate is one of the following types:



    [snip]





    • class type [snip], that has




      • [snip] (there are variations for different standard versions)


      • no user-provided, inherited, or explicit constructors (explicitly defaulted or deleted constructors are allowed)


      • [snip] (there are more rules, which apply to both classes)







    Given this definition, foo is an aggregate, while bar is not (it has user-provided, non-defaulted constructor).



    Therefore for foo, T object {arg1, arg2, ...}; is syntax for aggregate initialisation.




    The effects of aggregate initialization are:




    • [snip] (some details irrelevant to this case)


    • If the number of initializer clauses is less than the number of members or initializer list is completely empty, the remaining members are value-initialized.





    Therefore a.a is value initialised, which for int means zero initialisation.



    For bar, T object {}; on the other hand is value initialisation (of the class instance, not value initialisation of members!). Since it is a class type with a default constructor, the default constructor is called. The default constructor that you defined default initialises the members (by virtue of not having member initialisers), which in case of int (with non-static storage) leaves b.b with an indeterminate value.




    And for pod-types, the default initialization is zero-initialization.




    No. This is wrong.





    P.S. A word about your experiment and your conclusion: Seeing that output is zero does not necessarily mean that the variable was zero initialised. Zero is perfectly possible number for a garbage value.




    for that I ran the program maybe 5~6 times before posting and about 10 times now, a is always zero. b changes around a little.




    The fact that the value was same multiple times does not necessarily mean that it was initialised either.




    I also tried with set(CMAKE_CXX_STANDARD 14). The result was the same.




    The fact that result is the same with multiple compiler options doesn't mean that the variable is initialised. (Although in some cases, changing standard version can change whether it is initialised).




    How could I somehow shake my RAM a little so that if there was zero there, it should now be something else




    There is no guaranteed way in C++ to make uninitialised value value to appear nonzero.



    Only way to know that a variable is initialised is to compare program to the rules of the language and verify that the rules say that it is initialised. In this case a.a is indeed initialised.






    share|improve this answer


























    • "The default constructor that you defined default initialises the members (by virtue of not having member initialisers), which in case of int leaves it with an indeterminate value." --> eh! "for pod-types, the default initialization is zero-initialization." or am I wrong?

      – Joey Mallone
      11 hours ago








    • 2





      @JoeyMallone Default initialization of POD types is no initialization.

      – NathanOliver
      11 hours ago











    • @NathanOliver, Then I am even more confused. Then how come a is initialized. I was thinking a is default initialized and default initialization for a member POD is, zero-initialization. Is a then just luckily always coming up zero, no matter how many times I run this program.

      – Joey Mallone
      10 hours ago











    • @JoeyMallone Then how come a is initialized. Because it is value initialised. I was thinking a is default initialized It is not.

      – eerorika
      10 hours ago








    • 3





      @JoeyMallone Don't worry about it. You could make a book out of initialization in C++. If you get a chance CppCon on youtube has a few videos on initialization with the most disappointing (as in pointing out how bad it is) being youtube.com/watch?v=7DTlWPgX6zs

      – NathanOliver
      10 hours ago











    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/3.0/"u003ecc by-sa 3.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%2f54350114%2fc-zero-initialization-why-is-b-in-this-program-uninitialized-but-a-is-i%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    43














    The issue here is pretty subtle. You would think that



    bar::bar() = default;


    would give you a compiler generated default constructor, and it does, but it is now considered user provided. [dcl.fct.def.default]/5 states:




    Explicitly-defaulted functions and implicitly-declared functions are collectively called defaulted functions, and the implementation shall provide implicit definitions for them ([class.ctor] [class.dtor], [class.copy.ctor], [class.copy.assign]), which might mean defining them as deleted. A function is user-provided if it is user-declared and not explicitly defaulted or deleted on its first declaration. A user-provided explicitly-defaulted function (i.e., explicitly defaulted after its first declaration) is defined at the point where it is explicitly defaulted; if such a function is implicitly defined as deleted, the program is ill-formed. [ Note: Declaring a function as defaulted after its first declaration can provide efficient execution and concise definition while enabling a stable binary interface to an evolving code base. — end note ]




    emphasis mine



    So we can see that since you did not default bar() when you first declared it, it is now considered user provided. Because of that [dcl.init]/8.2




    if T is a (possibly cv-qualified) class type without a user-provided or deleted default constructor, then the object is zero-initialized and the semantic constraints for default-initialization are checked, and if T has a non-trivial default constructor, the object is default-initialized;




    no longer applies and we are not value initializing b but instead default initializing it per [dcl.init]/8.1




    if T is a (possibly cv-qualified) class type ([class]) with either no default constructor ([class.default.ctor]) or a default constructor that is user-provided or deleted, then the object is default-initialized;







    share|improve this answer





















    • 16





      I mean (*_*) .... If to even use the basic constructs of the language, I need to read the fine print of the language draft, then Hallelujah! But it probably seems to be what you say.

      – Joey Mallone
      11 hours ago






    • 5





      @balki Yes, doing bar::bar() = default out of line is the same as doing bar::bar(){} inline.

      – NathanOliver
      11 hours ago






    • 5





      @JoeyMallone Yeah, C++ can be pretty complicated. I'm not sure what the reason for this is.

      – NathanOliver
      11 hours ago






    • 3





      If there is a previous declaration, then a subsequent definition with the default keyword will NOT zero initialize the members. Right? This is correct. It is what is happening here.

      – NathanOliver
      10 hours ago






    • 3





      The reason is right there in your quote: the point of an out-of-line default is to "provide efficient execution and concise definition while enabling a stable binary interface to an evolving code base", in other words, enable you to switch to a user-written body later if necessary without breaking ABI. Note that the out-of-line definition is not implicitly inline and so can only appear in one TU by default; another TU seeing the class definition alone has no way to know if it's explicitly defined as defaulted.

      – T.C.
      6 hours ago


















    43














    The issue here is pretty subtle. You would think that



    bar::bar() = default;


    would give you a compiler generated default constructor, and it does, but it is now considered user provided. [dcl.fct.def.default]/5 states:




    Explicitly-defaulted functions and implicitly-declared functions are collectively called defaulted functions, and the implementation shall provide implicit definitions for them ([class.ctor] [class.dtor], [class.copy.ctor], [class.copy.assign]), which might mean defining them as deleted. A function is user-provided if it is user-declared and not explicitly defaulted or deleted on its first declaration. A user-provided explicitly-defaulted function (i.e., explicitly defaulted after its first declaration) is defined at the point where it is explicitly defaulted; if such a function is implicitly defined as deleted, the program is ill-formed. [ Note: Declaring a function as defaulted after its first declaration can provide efficient execution and concise definition while enabling a stable binary interface to an evolving code base. — end note ]




    emphasis mine



    So we can see that since you did not default bar() when you first declared it, it is now considered user provided. Because of that [dcl.init]/8.2




    if T is a (possibly cv-qualified) class type without a user-provided or deleted default constructor, then the object is zero-initialized and the semantic constraints for default-initialization are checked, and if T has a non-trivial default constructor, the object is default-initialized;




    no longer applies and we are not value initializing b but instead default initializing it per [dcl.init]/8.1




    if T is a (possibly cv-qualified) class type ([class]) with either no default constructor ([class.default.ctor]) or a default constructor that is user-provided or deleted, then the object is default-initialized;







    share|improve this answer





















    • 16





      I mean (*_*) .... If to even use the basic constructs of the language, I need to read the fine print of the language draft, then Hallelujah! But it probably seems to be what you say.

      – Joey Mallone
      11 hours ago






    • 5





      @balki Yes, doing bar::bar() = default out of line is the same as doing bar::bar(){} inline.

      – NathanOliver
      11 hours ago






    • 5





      @JoeyMallone Yeah, C++ can be pretty complicated. I'm not sure what the reason for this is.

      – NathanOliver
      11 hours ago






    • 3





      If there is a previous declaration, then a subsequent definition with the default keyword will NOT zero initialize the members. Right? This is correct. It is what is happening here.

      – NathanOliver
      10 hours ago






    • 3





      The reason is right there in your quote: the point of an out-of-line default is to "provide efficient execution and concise definition while enabling a stable binary interface to an evolving code base", in other words, enable you to switch to a user-written body later if necessary without breaking ABI. Note that the out-of-line definition is not implicitly inline and so can only appear in one TU by default; another TU seeing the class definition alone has no way to know if it's explicitly defined as defaulted.

      – T.C.
      6 hours ago
















    43












    43








    43







    The issue here is pretty subtle. You would think that



    bar::bar() = default;


    would give you a compiler generated default constructor, and it does, but it is now considered user provided. [dcl.fct.def.default]/5 states:




    Explicitly-defaulted functions and implicitly-declared functions are collectively called defaulted functions, and the implementation shall provide implicit definitions for them ([class.ctor] [class.dtor], [class.copy.ctor], [class.copy.assign]), which might mean defining them as deleted. A function is user-provided if it is user-declared and not explicitly defaulted or deleted on its first declaration. A user-provided explicitly-defaulted function (i.e., explicitly defaulted after its first declaration) is defined at the point where it is explicitly defaulted; if such a function is implicitly defined as deleted, the program is ill-formed. [ Note: Declaring a function as defaulted after its first declaration can provide efficient execution and concise definition while enabling a stable binary interface to an evolving code base. — end note ]




    emphasis mine



    So we can see that since you did not default bar() when you first declared it, it is now considered user provided. Because of that [dcl.init]/8.2




    if T is a (possibly cv-qualified) class type without a user-provided or deleted default constructor, then the object is zero-initialized and the semantic constraints for default-initialization are checked, and if T has a non-trivial default constructor, the object is default-initialized;




    no longer applies and we are not value initializing b but instead default initializing it per [dcl.init]/8.1




    if T is a (possibly cv-qualified) class type ([class]) with either no default constructor ([class.default.ctor]) or a default constructor that is user-provided or deleted, then the object is default-initialized;







    share|improve this answer















    The issue here is pretty subtle. You would think that



    bar::bar() = default;


    would give you a compiler generated default constructor, and it does, but it is now considered user provided. [dcl.fct.def.default]/5 states:




    Explicitly-defaulted functions and implicitly-declared functions are collectively called defaulted functions, and the implementation shall provide implicit definitions for them ([class.ctor] [class.dtor], [class.copy.ctor], [class.copy.assign]), which might mean defining them as deleted. A function is user-provided if it is user-declared and not explicitly defaulted or deleted on its first declaration. A user-provided explicitly-defaulted function (i.e., explicitly defaulted after its first declaration) is defined at the point where it is explicitly defaulted; if such a function is implicitly defined as deleted, the program is ill-formed. [ Note: Declaring a function as defaulted after its first declaration can provide efficient execution and concise definition while enabling a stable binary interface to an evolving code base. — end note ]




    emphasis mine



    So we can see that since you did not default bar() when you first declared it, it is now considered user provided. Because of that [dcl.init]/8.2




    if T is a (possibly cv-qualified) class type without a user-provided or deleted default constructor, then the object is zero-initialized and the semantic constraints for default-initialization are checked, and if T has a non-trivial default constructor, the object is default-initialized;




    no longer applies and we are not value initializing b but instead default initializing it per [dcl.init]/8.1




    if T is a (possibly cv-qualified) class type ([class]) with either no default constructor ([class.default.ctor]) or a default constructor that is user-provided or deleted, then the object is default-initialized;








    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited 11 hours ago

























    answered 11 hours ago









    NathanOliverNathanOliver

    89.9k15125190




    89.9k15125190








    • 16





      I mean (*_*) .... If to even use the basic constructs of the language, I need to read the fine print of the language draft, then Hallelujah! But it probably seems to be what you say.

      – Joey Mallone
      11 hours ago






    • 5





      @balki Yes, doing bar::bar() = default out of line is the same as doing bar::bar(){} inline.

      – NathanOliver
      11 hours ago






    • 5





      @JoeyMallone Yeah, C++ can be pretty complicated. I'm not sure what the reason for this is.

      – NathanOliver
      11 hours ago






    • 3





      If there is a previous declaration, then a subsequent definition with the default keyword will NOT zero initialize the members. Right? This is correct. It is what is happening here.

      – NathanOliver
      10 hours ago






    • 3





      The reason is right there in your quote: the point of an out-of-line default is to "provide efficient execution and concise definition while enabling a stable binary interface to an evolving code base", in other words, enable you to switch to a user-written body later if necessary without breaking ABI. Note that the out-of-line definition is not implicitly inline and so can only appear in one TU by default; another TU seeing the class definition alone has no way to know if it's explicitly defined as defaulted.

      – T.C.
      6 hours ago
















    • 16





      I mean (*_*) .... If to even use the basic constructs of the language, I need to read the fine print of the language draft, then Hallelujah! But it probably seems to be what you say.

      – Joey Mallone
      11 hours ago






    • 5





      @balki Yes, doing bar::bar() = default out of line is the same as doing bar::bar(){} inline.

      – NathanOliver
      11 hours ago






    • 5





      @JoeyMallone Yeah, C++ can be pretty complicated. I'm not sure what the reason for this is.

      – NathanOliver
      11 hours ago






    • 3





      If there is a previous declaration, then a subsequent definition with the default keyword will NOT zero initialize the members. Right? This is correct. It is what is happening here.

      – NathanOliver
      10 hours ago






    • 3





      The reason is right there in your quote: the point of an out-of-line default is to "provide efficient execution and concise definition while enabling a stable binary interface to an evolving code base", in other words, enable you to switch to a user-written body later if necessary without breaking ABI. Note that the out-of-line definition is not implicitly inline and so can only appear in one TU by default; another TU seeing the class definition alone has no way to know if it's explicitly defined as defaulted.

      – T.C.
      6 hours ago










    16




    16





    I mean (*_*) .... If to even use the basic constructs of the language, I need to read the fine print of the language draft, then Hallelujah! But it probably seems to be what you say.

    – Joey Mallone
    11 hours ago





    I mean (*_*) .... If to even use the basic constructs of the language, I need to read the fine print of the language draft, then Hallelujah! But it probably seems to be what you say.

    – Joey Mallone
    11 hours ago




    5




    5





    @balki Yes, doing bar::bar() = default out of line is the same as doing bar::bar(){} inline.

    – NathanOliver
    11 hours ago





    @balki Yes, doing bar::bar() = default out of line is the same as doing bar::bar(){} inline.

    – NathanOliver
    11 hours ago




    5




    5





    @JoeyMallone Yeah, C++ can be pretty complicated. I'm not sure what the reason for this is.

    – NathanOliver
    11 hours ago





    @JoeyMallone Yeah, C++ can be pretty complicated. I'm not sure what the reason for this is.

    – NathanOliver
    11 hours ago




    3




    3





    If there is a previous declaration, then a subsequent definition with the default keyword will NOT zero initialize the members. Right? This is correct. It is what is happening here.

    – NathanOliver
    10 hours ago





    If there is a previous declaration, then a subsequent definition with the default keyword will NOT zero initialize the members. Right? This is correct. It is what is happening here.

    – NathanOliver
    10 hours ago




    3




    3





    The reason is right there in your quote: the point of an out-of-line default is to "provide efficient execution and concise definition while enabling a stable binary interface to an evolving code base", in other words, enable you to switch to a user-written body later if necessary without breaking ABI. Note that the out-of-line definition is not implicitly inline and so can only appear in one TU by default; another TU seeing the class definition alone has no way to know if it's explicitly defined as defaulted.

    – T.C.
    6 hours ago







    The reason is right there in your quote: the point of an out-of-line default is to "provide efficient execution and concise definition while enabling a stable binary interface to an evolving code base", in other words, enable you to switch to a user-written body later if necessary without breaking ABI. Note that the out-of-line definition is not implicitly inline and so can only appear in one TU by default; another TU seeing the class definition alone has no way to know if it's explicitly defined as defaulted.

    – T.C.
    6 hours ago















    9














    The difference in behaviour comes from the fact that, according to [dcl.fct.def.default]/5, bar::bar is user-provided where foo::foo is not1. As a consequence, foo::foo will value-initialize its members (meaning: zero-initialize foo::a) but bar::bar will stay uninitialized2.





    1)[dcl.fct.def.default]/5




    A function is user-provided if it is user-declared and not explicitly defaulted or deleted on its first declaration.




    2)




    From [dcl.init#6]:




    To value-initialize an object of type T means:




    • if T is a (possibly cv-qualified) class type with either no default constructor ([class.ctor]) or a default constructor that is user-provided or deleted, then the object is default-initialized;


    • if T is a (possibly cv-qualified) class type without a user-provided or deleted default constructor, then the object is zero-initialized and the semantic constraints for default-initialization are checked, and if T has a non-trivial default constructor, the object is default-initialized;


    • ...





    From [dcl.init.list]:




    List-initialization of an object or reference of type T is defined as follows:




    • ...


    • Otherwise, if the initializer list has no elements and T is a class type with a default constructor, the object is value-initialized.






    From Vittorio Romeo's answer






    share|improve this answer






























      9














      The difference in behaviour comes from the fact that, according to [dcl.fct.def.default]/5, bar::bar is user-provided where foo::foo is not1. As a consequence, foo::foo will value-initialize its members (meaning: zero-initialize foo::a) but bar::bar will stay uninitialized2.





      1)[dcl.fct.def.default]/5




      A function is user-provided if it is user-declared and not explicitly defaulted or deleted on its first declaration.




      2)




      From [dcl.init#6]:




      To value-initialize an object of type T means:




      • if T is a (possibly cv-qualified) class type with either no default constructor ([class.ctor]) or a default constructor that is user-provided or deleted, then the object is default-initialized;


      • if T is a (possibly cv-qualified) class type without a user-provided or deleted default constructor, then the object is zero-initialized and the semantic constraints for default-initialization are checked, and if T has a non-trivial default constructor, the object is default-initialized;


      • ...





      From [dcl.init.list]:




      List-initialization of an object or reference of type T is defined as follows:




      • ...


      • Otherwise, if the initializer list has no elements and T is a class type with a default constructor, the object is value-initialized.






      From Vittorio Romeo's answer






      share|improve this answer




























        9












        9








        9







        The difference in behaviour comes from the fact that, according to [dcl.fct.def.default]/5, bar::bar is user-provided where foo::foo is not1. As a consequence, foo::foo will value-initialize its members (meaning: zero-initialize foo::a) but bar::bar will stay uninitialized2.





        1)[dcl.fct.def.default]/5




        A function is user-provided if it is user-declared and not explicitly defaulted or deleted on its first declaration.




        2)




        From [dcl.init#6]:




        To value-initialize an object of type T means:




        • if T is a (possibly cv-qualified) class type with either no default constructor ([class.ctor]) or a default constructor that is user-provided or deleted, then the object is default-initialized;


        • if T is a (possibly cv-qualified) class type without a user-provided or deleted default constructor, then the object is zero-initialized and the semantic constraints for default-initialization are checked, and if T has a non-trivial default constructor, the object is default-initialized;


        • ...





        From [dcl.init.list]:




        List-initialization of an object or reference of type T is defined as follows:




        • ...


        • Otherwise, if the initializer list has no elements and T is a class type with a default constructor, the object is value-initialized.






        From Vittorio Romeo's answer






        share|improve this answer















        The difference in behaviour comes from the fact that, according to [dcl.fct.def.default]/5, bar::bar is user-provided where foo::foo is not1. As a consequence, foo::foo will value-initialize its members (meaning: zero-initialize foo::a) but bar::bar will stay uninitialized2.





        1)[dcl.fct.def.default]/5




        A function is user-provided if it is user-declared and not explicitly defaulted or deleted on its first declaration.




        2)




        From [dcl.init#6]:




        To value-initialize an object of type T means:




        • if T is a (possibly cv-qualified) class type with either no default constructor ([class.ctor]) or a default constructor that is user-provided or deleted, then the object is default-initialized;


        • if T is a (possibly cv-qualified) class type without a user-provided or deleted default constructor, then the object is zero-initialized and the semantic constraints for default-initialization are checked, and if T has a non-trivial default constructor, the object is default-initialized;


        • ...





        From [dcl.init.list]:




        List-initialization of an object or reference of type T is defined as follows:




        • ...


        • Otherwise, if the initializer list has no elements and T is a class type with a default constructor, the object is value-initialized.






        From Vittorio Romeo's answer







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited 11 hours ago

























        answered 11 hours ago









        YSCYSC

        21.4k349101




        21.4k349101























            3














            From cppreference:




            Aggregate initialization initializes aggregates. It is a form of list-initialization.



            An aggregate is one of the following types:



            [snip]





            • class type [snip], that has




              • [snip] (there are variations for different standard versions)


              • no user-provided, inherited, or explicit constructors (explicitly defaulted or deleted constructors are allowed)


              • [snip] (there are more rules, which apply to both classes)







            Given this definition, foo is an aggregate, while bar is not (it has user-provided, non-defaulted constructor).



            Therefore for foo, T object {arg1, arg2, ...}; is syntax for aggregate initialisation.




            The effects of aggregate initialization are:




            • [snip] (some details irrelevant to this case)


            • If the number of initializer clauses is less than the number of members or initializer list is completely empty, the remaining members are value-initialized.





            Therefore a.a is value initialised, which for int means zero initialisation.



            For bar, T object {}; on the other hand is value initialisation (of the class instance, not value initialisation of members!). Since it is a class type with a default constructor, the default constructor is called. The default constructor that you defined default initialises the members (by virtue of not having member initialisers), which in case of int (with non-static storage) leaves b.b with an indeterminate value.




            And for pod-types, the default initialization is zero-initialization.




            No. This is wrong.





            P.S. A word about your experiment and your conclusion: Seeing that output is zero does not necessarily mean that the variable was zero initialised. Zero is perfectly possible number for a garbage value.




            for that I ran the program maybe 5~6 times before posting and about 10 times now, a is always zero. b changes around a little.




            The fact that the value was same multiple times does not necessarily mean that it was initialised either.




            I also tried with set(CMAKE_CXX_STANDARD 14). The result was the same.




            The fact that result is the same with multiple compiler options doesn't mean that the variable is initialised. (Although in some cases, changing standard version can change whether it is initialised).




            How could I somehow shake my RAM a little so that if there was zero there, it should now be something else




            There is no guaranteed way in C++ to make uninitialised value value to appear nonzero.



            Only way to know that a variable is initialised is to compare program to the rules of the language and verify that the rules say that it is initialised. In this case a.a is indeed initialised.






            share|improve this answer


























            • "The default constructor that you defined default initialises the members (by virtue of not having member initialisers), which in case of int leaves it with an indeterminate value." --> eh! "for pod-types, the default initialization is zero-initialization." or am I wrong?

              – Joey Mallone
              11 hours ago








            • 2





              @JoeyMallone Default initialization of POD types is no initialization.

              – NathanOliver
              11 hours ago











            • @NathanOliver, Then I am even more confused. Then how come a is initialized. I was thinking a is default initialized and default initialization for a member POD is, zero-initialization. Is a then just luckily always coming up zero, no matter how many times I run this program.

              – Joey Mallone
              10 hours ago











            • @JoeyMallone Then how come a is initialized. Because it is value initialised. I was thinking a is default initialized It is not.

              – eerorika
              10 hours ago








            • 3





              @JoeyMallone Don't worry about it. You could make a book out of initialization in C++. If you get a chance CppCon on youtube has a few videos on initialization with the most disappointing (as in pointing out how bad it is) being youtube.com/watch?v=7DTlWPgX6zs

              – NathanOliver
              10 hours ago
















            3














            From cppreference:




            Aggregate initialization initializes aggregates. It is a form of list-initialization.



            An aggregate is one of the following types:



            [snip]





            • class type [snip], that has




              • [snip] (there are variations for different standard versions)


              • no user-provided, inherited, or explicit constructors (explicitly defaulted or deleted constructors are allowed)


              • [snip] (there are more rules, which apply to both classes)







            Given this definition, foo is an aggregate, while bar is not (it has user-provided, non-defaulted constructor).



            Therefore for foo, T object {arg1, arg2, ...}; is syntax for aggregate initialisation.




            The effects of aggregate initialization are:




            • [snip] (some details irrelevant to this case)


            • If the number of initializer clauses is less than the number of members or initializer list is completely empty, the remaining members are value-initialized.





            Therefore a.a is value initialised, which for int means zero initialisation.



            For bar, T object {}; on the other hand is value initialisation (of the class instance, not value initialisation of members!). Since it is a class type with a default constructor, the default constructor is called. The default constructor that you defined default initialises the members (by virtue of not having member initialisers), which in case of int (with non-static storage) leaves b.b with an indeterminate value.




            And for pod-types, the default initialization is zero-initialization.




            No. This is wrong.





            P.S. A word about your experiment and your conclusion: Seeing that output is zero does not necessarily mean that the variable was zero initialised. Zero is perfectly possible number for a garbage value.




            for that I ran the program maybe 5~6 times before posting and about 10 times now, a is always zero. b changes around a little.




            The fact that the value was same multiple times does not necessarily mean that it was initialised either.




            I also tried with set(CMAKE_CXX_STANDARD 14). The result was the same.




            The fact that result is the same with multiple compiler options doesn't mean that the variable is initialised. (Although in some cases, changing standard version can change whether it is initialised).




            How could I somehow shake my RAM a little so that if there was zero there, it should now be something else




            There is no guaranteed way in C++ to make uninitialised value value to appear nonzero.



            Only way to know that a variable is initialised is to compare program to the rules of the language and verify that the rules say that it is initialised. In this case a.a is indeed initialised.






            share|improve this answer


























            • "The default constructor that you defined default initialises the members (by virtue of not having member initialisers), which in case of int leaves it with an indeterminate value." --> eh! "for pod-types, the default initialization is zero-initialization." or am I wrong?

              – Joey Mallone
              11 hours ago








            • 2





              @JoeyMallone Default initialization of POD types is no initialization.

              – NathanOliver
              11 hours ago











            • @NathanOliver, Then I am even more confused. Then how come a is initialized. I was thinking a is default initialized and default initialization for a member POD is, zero-initialization. Is a then just luckily always coming up zero, no matter how many times I run this program.

              – Joey Mallone
              10 hours ago











            • @JoeyMallone Then how come a is initialized. Because it is value initialised. I was thinking a is default initialized It is not.

              – eerorika
              10 hours ago








            • 3





              @JoeyMallone Don't worry about it. You could make a book out of initialization in C++. If you get a chance CppCon on youtube has a few videos on initialization with the most disappointing (as in pointing out how bad it is) being youtube.com/watch?v=7DTlWPgX6zs

              – NathanOliver
              10 hours ago














            3












            3








            3







            From cppreference:




            Aggregate initialization initializes aggregates. It is a form of list-initialization.



            An aggregate is one of the following types:



            [snip]





            • class type [snip], that has




              • [snip] (there are variations for different standard versions)


              • no user-provided, inherited, or explicit constructors (explicitly defaulted or deleted constructors are allowed)


              • [snip] (there are more rules, which apply to both classes)







            Given this definition, foo is an aggregate, while bar is not (it has user-provided, non-defaulted constructor).



            Therefore for foo, T object {arg1, arg2, ...}; is syntax for aggregate initialisation.




            The effects of aggregate initialization are:




            • [snip] (some details irrelevant to this case)


            • If the number of initializer clauses is less than the number of members or initializer list is completely empty, the remaining members are value-initialized.





            Therefore a.a is value initialised, which for int means zero initialisation.



            For bar, T object {}; on the other hand is value initialisation (of the class instance, not value initialisation of members!). Since it is a class type with a default constructor, the default constructor is called. The default constructor that you defined default initialises the members (by virtue of not having member initialisers), which in case of int (with non-static storage) leaves b.b with an indeterminate value.




            And for pod-types, the default initialization is zero-initialization.




            No. This is wrong.





            P.S. A word about your experiment and your conclusion: Seeing that output is zero does not necessarily mean that the variable was zero initialised. Zero is perfectly possible number for a garbage value.




            for that I ran the program maybe 5~6 times before posting and about 10 times now, a is always zero. b changes around a little.




            The fact that the value was same multiple times does not necessarily mean that it was initialised either.




            I also tried with set(CMAKE_CXX_STANDARD 14). The result was the same.




            The fact that result is the same with multiple compiler options doesn't mean that the variable is initialised. (Although in some cases, changing standard version can change whether it is initialised).




            How could I somehow shake my RAM a little so that if there was zero there, it should now be something else




            There is no guaranteed way in C++ to make uninitialised value value to appear nonzero.



            Only way to know that a variable is initialised is to compare program to the rules of the language and verify that the rules say that it is initialised. In this case a.a is indeed initialised.






            share|improve this answer















            From cppreference:




            Aggregate initialization initializes aggregates. It is a form of list-initialization.



            An aggregate is one of the following types:



            [snip]





            • class type [snip], that has




              • [snip] (there are variations for different standard versions)


              • no user-provided, inherited, or explicit constructors (explicitly defaulted or deleted constructors are allowed)


              • [snip] (there are more rules, which apply to both classes)







            Given this definition, foo is an aggregate, while bar is not (it has user-provided, non-defaulted constructor).



            Therefore for foo, T object {arg1, arg2, ...}; is syntax for aggregate initialisation.




            The effects of aggregate initialization are:




            • [snip] (some details irrelevant to this case)


            • If the number of initializer clauses is less than the number of members or initializer list is completely empty, the remaining members are value-initialized.





            Therefore a.a is value initialised, which for int means zero initialisation.



            For bar, T object {}; on the other hand is value initialisation (of the class instance, not value initialisation of members!). Since it is a class type with a default constructor, the default constructor is called. The default constructor that you defined default initialises the members (by virtue of not having member initialisers), which in case of int (with non-static storage) leaves b.b with an indeterminate value.




            And for pod-types, the default initialization is zero-initialization.




            No. This is wrong.





            P.S. A word about your experiment and your conclusion: Seeing that output is zero does not necessarily mean that the variable was zero initialised. Zero is perfectly possible number for a garbage value.




            for that I ran the program maybe 5~6 times before posting and about 10 times now, a is always zero. b changes around a little.




            The fact that the value was same multiple times does not necessarily mean that it was initialised either.




            I also tried with set(CMAKE_CXX_STANDARD 14). The result was the same.




            The fact that result is the same with multiple compiler options doesn't mean that the variable is initialised. (Although in some cases, changing standard version can change whether it is initialised).




            How could I somehow shake my RAM a little so that if there was zero there, it should now be something else




            There is no guaranteed way in C++ to make uninitialised value value to appear nonzero.



            Only way to know that a variable is initialised is to compare program to the rules of the language and verify that the rules say that it is initialised. In this case a.a is indeed initialised.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited 10 hours ago

























            answered 11 hours ago









            eerorikaeerorika

            79.2k557119




            79.2k557119













            • "The default constructor that you defined default initialises the members (by virtue of not having member initialisers), which in case of int leaves it with an indeterminate value." --> eh! "for pod-types, the default initialization is zero-initialization." or am I wrong?

              – Joey Mallone
              11 hours ago








            • 2





              @JoeyMallone Default initialization of POD types is no initialization.

              – NathanOliver
              11 hours ago











            • @NathanOliver, Then I am even more confused. Then how come a is initialized. I was thinking a is default initialized and default initialization for a member POD is, zero-initialization. Is a then just luckily always coming up zero, no matter how many times I run this program.

              – Joey Mallone
              10 hours ago











            • @JoeyMallone Then how come a is initialized. Because it is value initialised. I was thinking a is default initialized It is not.

              – eerorika
              10 hours ago








            • 3





              @JoeyMallone Don't worry about it. You could make a book out of initialization in C++. If you get a chance CppCon on youtube has a few videos on initialization with the most disappointing (as in pointing out how bad it is) being youtube.com/watch?v=7DTlWPgX6zs

              – NathanOliver
              10 hours ago



















            • "The default constructor that you defined default initialises the members (by virtue of not having member initialisers), which in case of int leaves it with an indeterminate value." --> eh! "for pod-types, the default initialization is zero-initialization." or am I wrong?

              – Joey Mallone
              11 hours ago








            • 2





              @JoeyMallone Default initialization of POD types is no initialization.

              – NathanOliver
              11 hours ago











            • @NathanOliver, Then I am even more confused. Then how come a is initialized. I was thinking a is default initialized and default initialization for a member POD is, zero-initialization. Is a then just luckily always coming up zero, no matter how many times I run this program.

              – Joey Mallone
              10 hours ago











            • @JoeyMallone Then how come a is initialized. Because it is value initialised. I was thinking a is default initialized It is not.

              – eerorika
              10 hours ago








            • 3





              @JoeyMallone Don't worry about it. You could make a book out of initialization in C++. If you get a chance CppCon on youtube has a few videos on initialization with the most disappointing (as in pointing out how bad it is) being youtube.com/watch?v=7DTlWPgX6zs

              – NathanOliver
              10 hours ago

















            "The default constructor that you defined default initialises the members (by virtue of not having member initialisers), which in case of int leaves it with an indeterminate value." --> eh! "for pod-types, the default initialization is zero-initialization." or am I wrong?

            – Joey Mallone
            11 hours ago







            "The default constructor that you defined default initialises the members (by virtue of not having member initialisers), which in case of int leaves it with an indeterminate value." --> eh! "for pod-types, the default initialization is zero-initialization." or am I wrong?

            – Joey Mallone
            11 hours ago






            2




            2





            @JoeyMallone Default initialization of POD types is no initialization.

            – NathanOliver
            11 hours ago





            @JoeyMallone Default initialization of POD types is no initialization.

            – NathanOliver
            11 hours ago













            @NathanOliver, Then I am even more confused. Then how come a is initialized. I was thinking a is default initialized and default initialization for a member POD is, zero-initialization. Is a then just luckily always coming up zero, no matter how many times I run this program.

            – Joey Mallone
            10 hours ago





            @NathanOliver, Then I am even more confused. Then how come a is initialized. I was thinking a is default initialized and default initialization for a member POD is, zero-initialization. Is a then just luckily always coming up zero, no matter how many times I run this program.

            – Joey Mallone
            10 hours ago













            @JoeyMallone Then how come a is initialized. Because it is value initialised. I was thinking a is default initialized It is not.

            – eerorika
            10 hours ago







            @JoeyMallone Then how come a is initialized. Because it is value initialised. I was thinking a is default initialized It is not.

            – eerorika
            10 hours ago






            3




            3





            @JoeyMallone Don't worry about it. You could make a book out of initialization in C++. If you get a chance CppCon on youtube has a few videos on initialization with the most disappointing (as in pointing out how bad it is) being youtube.com/watch?v=7DTlWPgX6zs

            – NathanOliver
            10 hours ago





            @JoeyMallone Don't worry about it. You could make a book out of initialization in C++. If you get a chance CppCon on youtube has a few videos on initialization with the most disappointing (as in pointing out how bad it is) being youtube.com/watch?v=7DTlWPgX6zs

            – NathanOliver
            10 hours ago


















            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%2f54350114%2fc-zero-initialization-why-is-b-in-this-program-uninitialized-but-a-is-i%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

            Plaza Victoria

            In PowerPoint, is there a keyboard shortcut for bulleted / numbered list?

            How to put 3 figures in Latex with 2 figures side by side and 1 below these side by side images but in...