2

I am using Visual Studio 2013.

I have the following code

class Foo{
public:
     Foo(){};
     Foo* fPtr;
     float f;
};

int main()
{
    Foo foo1; // No Warning. fPtr is initialized to NULL, f is set to 0.0.
    Foo foo2(foo1); // Compiles fine. Uses compiler generated copy constructor
    return 0;
}

Now consider the same code but without the user defined default constructor.

class Foo{
public:
               // No user defined default constructor, or equivalently
               // Foo() = default;
     Foo* fPtr;
     float f;
};

int main()
{
    Foo foo1; // Neither fPtr nor f are initialized, both contain garbage.
   //Foo foo2(foo1); // error C4700: uninitialized local variable 'foo1' used
    return 0;
}

I thought that the user defined default constructor and the implicitly defined default constructor are equivalent, but it seems to me they are not.

How exactly does the compiler defined default constructor work?

After this case, I am cautious against using compiler defined default constructors and always provide my own, even though sometimes empty default constructors. Am I misunderstanding something?

1 Answer 1

6

On implementation, the implicitly-defined default constructor does the same thing as the user-defined constructor with empty body and empty initializer list.

If the implicitly-declared default constructor is not defined as deleted, it is defined (that is, a function body is generated and compiled) by the compiler if odr-used, and it has exactly the same effect as a user-defined constructor with empty body and empty initializer list.

And

Foo foo1; // No Warning. fPtr is initialized to NULL, f is set to 0.0.

No. Not only for the 2nd code sample, even for the 1st code sample, foo1.fPtr and foo1.f are not initialized; the empty user-defined constructor doesn't initialize any members at all.

And about the compiler warning, it seems that MSVS thinks if a user-defined constructor is provided and invoked, then the object could be supposed that have been initialized. But you need to make sure that the constructor does or doesn't do what you expected.

Note that they still have some subtle different side effects; such as for list initialization and value intialization, (but not default initialization used here). e.g. for

Foo foo1{};

Then for the 1st case, the user-defined default constructor will be called; since it does nothing foo1.fPtr and foo1.f will still be uninitialized; But for the 2nd case, aggregate initialization will be performed (because of the missing of user-defined constructor), then foo1.fPtr and foo1.f will be value-initialized. i.e. foo1.fPtr is initialized to nullptr, foo1.f is initialized to 0.

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

10 Comments

I do not quite understand what you mean by "No. Even for the 1st code sample, foo1.fPtr and foo1.f are not initialized; the user-defined constructor does nothing in fact.". The fact is that in the first case the user defined constructor is called both with Foo foo1; and Foo foo1{} and the members are correctly initialized to their default values, i.e. NULL and 0.0, so I assume the user defined constructor indeed does something.
@Hrachya_h No, they're not initialized, for example rextester.com/JVFH58493.
Foo foo1; DOES NOT initialize the members in both examples, due to lack of any initialization. If they are getting initialized to zeros, it is random undefined behavior by the compiler. It is NOT guaranteed in these examples.
"The implicitly-defined default constructor does the same thing as the user-defined constructor with empty body and empty initializer list." Has that changed recently? Because it didn't use to. Value initialization with the implicitly defined constructor would zero initialize members, and do nothing in the case of a user defined constructor with empty etc etc. You seem to say as much in the last paragraph.
@juanchopanza I meant for the implementation, the implicitly-defined default constructor does the same thing as the empty user-defined constructor. Yes they have different side effects for value-intialization and list-initialization(aggregate-initialization).
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.