13

Before you start to mark this as duplicate I've already read this .But It doesn't answer my question. The linked question talks about C++98 & C++03 but my question is about defaulted constructor introduced by C++11.

Consider following program (See live demo here):

#include <iostream> struct Test { int s; float m; Test(int a,float b) : s(a),m(b) { } Test()=default; }t; int main() { std::cout<<t.s<<'\n'; std::cout<<t.m<<'\n'; } 

My question is that is the defaulted constructor provided by compiler here always initializes built in types to by default 0 in C++11 & C++14 when they are class & struct members. Is this behavior guaranteed by C++11 standard?

8
  • Who voted to close? Why? Commented Oct 30, 2015 at 16:55
  • 4
    see the wiki's entry on default-initialization Commented Oct 30, 2015 at 16:56
  • 7
    However, you declared t as a global, so it would be value/zero initialized anyway IIRC Commented Oct 30, 2015 at 16:57
  • 1
    @PravasiMeet "Who voted to close? Why?" Regarding the why, you've got enough rep to check yourself. But I agree it's a valid and valuable question. I've just been falling into the same pit, with my (now removed) comment. Commented Oct 30, 2015 at 17:03
  • @πάνταῥεῖ: how to check that? I really don't know. Commented Oct 30, 2015 at 17:06

5 Answers 5

17

There are two separate questions built into this question.

  1. What does = default mean for the default constructor? From [class.ctor]:

    A default constructor that is defaulted and not defined as deleted is implicitly defined when it is odr-used (3.2) to create an object of its class type (1.8) or when it is explicitly defaulted after its first declaration. The implicitly-defined default constructor performs the set of initializations of the class that would be performed by a user-written default constructor for that class with no ctor-initializer (12.6.2) and an empty compound-statement.

    That is, Test() = default is exactly equivalent to Test() { }, which would default-initialize s and m, which sets them to some indeterminate value.

  2. How are t.s and t.m initialized? Yes, this is a separate question from (1) because we're not just calling the default constructor here. From [basic.stc.static]:

    All variables which do not have dynamic storage duration, do not have thread storage duration, and are not local have static storage duration.

    and from [basic.start.init]:

    Variables with static storage duration (3.7.1) or thread storage duration (3.7.2) shall be zero-initialized (8.5) before any other initialization takes place.

    Thus t.s and t.m are guaranteed to be 0, even though if we default-constructed a local Test, they would not be.

Sign up to request clarification or add additional context in comments.

7 Comments

Does this work for union members? Does this make sense?
@curiousguy Zero-initialization for a union means "the object’s first non-static named data member is zero-initialized and padding is initialized to zero bits;"
"Test() = default is exactly equivalent to Test() { }": nearly right, it is potentially trivial though. And you want your constructors and destructors be trivial whenever you can.
Is the static-storage zero-initialization of s and m guarenteed to survive the constructor call? I.e., if a constructor does not initialize a member, does that mean "the memory contained the member is unchanged" or does it mean that "the compiler can do whatever it likes"?
@Barry So "Variables with static storage duration (3.7.1) or thread storage duration (3.7.2) shall be zero-initialized (8.5) before any other initialization takes place"? don't apply to union members?
|
8

Test = default will default initialize its members. but for type as int or float, default initialization is different than value-initialization

so

Test t; // t.s and t.m have unitialized value 

whereas

Test t{}; // t.s == 0 and t.m == 0.0f; 

6 Comments

What is the definition of Test t{}?
@curiousguy: It constructs t with value-initialization, similar to Test t = Test();. Test t(); would be a function declaration: see Most-vexing-parse.
How is value init of Test not default init?
int does not have constructors.
@curiousguy If a type has any constructor, there's no difference between value-initialization and default-initialization, both just call the default-constructor,
|
6

As it is already answered, it is not guaranteed that default constructor will "initialize built in types automatically to 0".

You can use placement new to see this for yourself. Consider the following code:

#include <iostream> struct Test { int s; float m; Test(int a,float b) : s(a),m(b) { } Test()=default; }; int main() { char* buf = new char[sizeof(Test)]; Test* t = new (buf) Test; std::cout << t->s << '\n'; std::cout << t->m <<'\n'; t->s = 42; t->m = 4.2; t->~Test(); t = new (buf) Test; std::cout << t->s << '\n'; std::cout << t->m <<'\n'; } 

If default constructor was guaranteed to zero-initialize data members on non-class types, the output of this program would be four zeroes.

However, you'll likely see something like this instead:

0 0 42 4.2 

Here's this code on cpp.sh - http://cpp.sh/9fdj

1 Comment

Nice trick to test default/value init, but notice the OP has a t with different storage type, which changes the answer.
3

No, the default constructor doesn't do anything! To initialize the member variables you can write:

struct Test { int s = 0; float m = 3.3; Test(int a,float b) : s(a),m(b) { } Test()=default; }; 

Look at this: C++ ctor = default

Comments

2

For all purposes:

Test() = default; 

is equivalent to:

Test() {} 

So it does not initialize members of built-in types.

6 Comments

What does "for all purposes" mean?
Not the same if trivially constructible is one of those purposes
I really don't think this is true. Test()=default would lead to value initialization of Test resulting in zero initialization of s and m. Test() {} would break that.
@juanchopanza 12.1 "The implicitly-defined default constructor performs the set of initializations of the class that would be performed by a user-written default constructor for that class with no ctor-initializer and an empty compound-statement."
Ah yes, value initialization's behavior depends on whether there's a "user-provided" constructor, so there Test()=default; is different from Test() {}.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.