3

Bjarne wrote:-
For a type T, T() is the notation for the default value , as defined by the default constructor . What happen when we don't declare default constructor ? For example

using namespace std;

class date{
    int n,m;
    public:
   int day(){return n;}
   int month(){return m;}
          };//no default constructor

int main()
{
     date any =date();
     cout<<any.month()<<endl;   
     cout<<any.day()<<endl;
return 0;

}

Output of this program is 0 and 0 every time i run my program. I haven't declare any default constructor then why there exits a default value i.e. 0?

EDIT-

    class date{
        int n,m;
        public:
        date (){
        m=1;}
       int day(){return n;}
       int month(){return m;}
     };

 int main()
  {
     date any =date();
     cout<<any.month()<<endl;   
     cout<<any.day()<<endl;
return 0;

}

After reading answers i provide a default constructor but now n is getting garbage value but according to answers it should be 0 as m is out of reach of any other constructor and it is value initialisation as mentioned in answer

3 Answers 3

5

The behavior you see is Well-Defined for your class.


How & Why is the behavior Well-Defined?

The rule is:
If you do not provide a no argument constructor the compiler generates one for your program in case your program needs one.
Caveat:
The compiler does not generate the no argument constructor if your program defines any constructor for the class.

As per the C++ Standard an object can be initialized in 3 ways:

  • Zero Initialization
  • Default Initialization &
  • Value Initialization

When, a type name or constructor initializer is followed by () the initialization is through value initialization.

Thus,

date any =date();
              ^^^

Value Initializes an nameless object and then copies it in to the local object any, while:

date any;

would be a Default Initialization.

Value Initialization gives an initial value of zero to members that are out of reach of any constructor.
In your program, n and m are beyond the reach of any constructor and hence get initialized to 0.


Answer to Edited Question:
In your edited case, your class provides a no argument constructor, date(), which is capable(& should) initialize members n and m, but this constructor doesn't initialize both the members, So In this case no zero initialization takes place, and the uninitialized members in the object have an Indeterminate(any random) value, further this temporary object is copied to any object which displays the shows indeterminate member values.


For Standerdese Fans:
The rules for object Initialization are aptly defined in:

C++03 Standard 8.5/5:

To zero-initialize an object of type T means:
— if T is a scalar type (3.9), the object is set to the value of 0 (zero) converted to T;
— if T is a non-union class type, each nonstatic data member and each base-class subobject is zero-initialized;
— if T is a union type, the object’s first named data member is zero-initialized;
— if T is an array type, each element is zero-initialized;
— if T is a reference type, no initialization is performed.

To default-initialize an object of type T means:
— if T is a non-POD class type (clause 9), the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
— if T is an array type, each element is default-initialized;
— otherwise, the object is zero-initialized.

To value-initialize an object of type T means:
— if T is a class type (clause 9) with a user-declared constructor (12.1), then the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
— if T is a non-union class type without a user-declared constructor, then every non-static data member and base-class component of T is value-initialized;
— if T is an array type, then each element is value-initialized;
— otherwise, the object is zero-initialized

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

12 Comments

Using date any; does not initialize it. date any = date(); will call compiler-generated default constructor which in turn will call default constructors for all base classes and members. For int default constructor is int(). And it will initialize int members to 0. You can see for yourself link
@AzzA: Just because a program shows observable behavior it does not mean it is correct.Anyhow I edited the answer to add the Standard specification which explains why it works this way. And Yes, I don't mind editing my wrong answers to correct ones.
It is correct behavior. This compiler-generated default constructor will also initialize vtable if there is need. So this is correct and anticipated behavior.
@AzzA: Can you provide the reference from the Standard which says default constructor will initialize v-table? That is a sweeping statement, The standard does not mention v-table at all, dynamic dispatch is a implementation detail.Don't rely & base your fundamentals on observable behaviors, Undefined & Unspecified behaviors can show you any behavior.
Sorry, I meant, vptr, not vtable. And, yes, technically, you are correct - this is implementation specific. But, say, on those implementations that put vptr into instances (and I don't know if there are any that don't; mainstream do that) , compiler-generated default constructor will initialize vptr. But, yes, since Standard leaves vptr up to implementation, it does not say anything about it, I suppose. Which is very useful to know.
|
4

Because compiler, cursing under its breath, generates one for you.

EDIT: Since Als said it does not answer question, I'll elaborate. When you use date any = date();, you call compiler-generated default constructor. This constructor calls default constructors for all base classes and data members. For your data members int default constructor is int(), which sets value to 0. Here is code on ideone.com

#include <iostream>

int main( void )
{
 int i = -123;

 i = int(); 

 std::cout << i << std::endl; 


 return( 0 );
}

Program output:

0

3 Comments

@Als Yes, it does. And see my comment to your answer.
:what i do next is provide a default constructor like this` date (){m=1;}`but now n is getting garbage value . but it is not calling int() for n to make it zero
@T.J. date::date() : n(), m( 1 ) {}
0

From the C++ draft standard (December 1996 Working Paper):

If there is no user-declared constructor for class X, a default constructor is implicitly declared. An implicitly-declared default constructor is an inline public member of its class.

Comments

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.