default-values to class members

J

Joel

Is it true that if we don't specify a default constructor for
our class, then the C# compiler provides us with its own
that zeroes (or assigns default values) to the data members?

I wrote a no-parameter constructor for my class with an
empty function body. I then instantiated an object and tried
printing its values, amazingly the members were already initialized.
But how is this possible if I have not included any code for doing
so. The compiler obviously hasn't generated a constructor for
initialization because I have my own constructor (without any params).
The same thing happens when I write a constructor with parameters,
in this case, again, C# does not provide a default constructor but
yet the values are get initialized.

I tried using ILDASM to see what was going on, .. and System.Object's
constructor was being called at the beginning of my constructor's
body.
This was the only code that the compiler had generated.
Is it System.Object's constructor then that does the work of
initializing
the members. This doesn't make much sense because how can base class's
constructor get access to derived class's members!

Thanks for any help,

~ Joel
 
?

=?ISO-8859-1?Q?Arne_Vajh=F8j?=

Joel said:
Is it true that if we don't specify a default constructor for
our class, then the C# compiler provides us with its own
that zeroes (or assigns default values) to the data members?

I wrote a no-parameter constructor for my class with an
empty function body. I then instantiated an object and tried
printing its values, amazingly the members were already initialized.
But how is this possible if I have not included any code for doing
so. The compiler obviously hasn't generated a constructor for
initialization because I have my own constructor (without any params).
The same thing happens when I write a constructor with parameters,
in this case, again, C# does not provide a default constructor but
yet the values are get initialized.

Members are in the and locations in memory.

Locations in memory always has a value.

There are only a couple possibilities:
* the language/framework does not init so they
keep their values from last usage
* the language/framework does init

..NET init so they become 0, 0.0, null etc..

Arne
 
J

Joel

Locations in memory always has a value.
There are only a couple possibilities:
* the language/framework does not init so they
keep their values from last usage
* the language/framework does init

.NET init so they become 0, 0.0, null etc..

That's very obvious, but I'm looking for exact behavior of the default
constructor generated by the csharp compiler.

Thanks

Joel
 
C

ClayB

The compiler does the initializations for you. Here is some
information from section 5.2 of C# specifications which you can find
at:
http://msdn2.microsoft.com/en-us/vcsharp/aa336809.aspx

5.2 Default values
The following categories of variables are automatically initialized to
their default values:
• Static variables.
• Instance variables of class instances.
• Array elements.
The default value of a variable depends on the type of the variable
and is determined as follows:
• For a variable of a value-type, the default value is the same as the
value computed by the value-type’s default constructor (§‎0).
• For a variable of a reference-type, the default value is null.
Initialization to default values is typically done by having the
memory manager or garbage collector initialize memory to all-bits-zero
before it is allocated for use. For this reason, it is convenient to
use all-bits-zero to represent the null reference.

================
Clay Burch
 
?

=?ISO-8859-1?Q?Arne_Vajh=F8j?=

Joel said:
That's very obvious, but I'm looking for exact behavior of the default
constructor generated by the csharp compiler.

It has nothing to do with default constructor.

If you know C then the memory is allocated
with calloc not malloc.

Arne
 
J

Joel

MSDN:
"If you do not provide a constructor for your object, C# will create
one by default that instantiates the object and sets any member
variables to the default values listed here: Default Values Table (C#
Reference). Static classes and structs can also have constructors."

I want to know, If I provide my class with a constructor, then the
member variables are not supposed to be set to their default values,
and I'm supposed to do that right?
Surprisingly, the compiler doesn't complaint if I don't initialize
them, and it gets initialized automaticaly. Why is this happening?

For structs, the behavior is different, and any constructors that I
provide must initialize all the members to values else the compiler
flags an error.

Thanks

Joel
 
M

Marc Gravell

class fields are *always* initialised *before* handing to your
constructor. In effect, this means zero or null for value-types and
reference-types respectively [before any initialisation values such as
"private int i = 5;" are taken into account].

Conversely, structs leave the initialisation to the ctor. The default
ctor (which cannot be removed) sets everything to 0 / null; otherwise,
you must assign everything, and note also that you can't read a field
that hasn't yet been definitely assigned.

Marc
 
W

Willy Denoyette [MVP]

Joel said:
MSDN:
"If you do not provide a constructor for your object, C# will create
one by default that instantiates the object and sets any member
variables to the default values listed here: Default Values Table (C#
Reference). Static classes and structs can also have constructors."

I want to know, If I provide my class with a constructor, then the
member variables are not supposed to be set to their default values,
and I'm supposed to do that right?
Surprisingly, the compiler doesn't complaint if I don't initialize
them, and it gets initialized automaticaly. Why is this happening?

For structs, the behavior is different, and any constructors that I
provide must initialize all the members to values else the compiler
flags an error.

Thanks

Joel

Arne's gave you the right answer. The default values come from the fact that the memory
allocated for the object's instance is set to all 0 (binary) by the CLR, the default
constructor has nothing to do with this at all.
The result is that all members have their initial values set to what happens to be their
default.
References are set null, integer types are set to 0, floats and doubles are set to ... 0.
Your constructor can initialize a member to another value than the default, but that doesn't
affect the defaults of the other members.

Willy.
 
J

Joel

After going through some IL code and documentation, and reading, I
came up with the following:

(1) Whenever an object for a derived class is instantiated, the
constructor of the derived class executes first, this first job of
this constructor is to call its base class's constructor. The base
class's constructor now calls its base class's constructor and so on
which ultimately results in a call to the constructor of
system.Object. So the sequence shown by Jon Skeet wouldn't be correct
strictly speaking. Ofcourse, the effect is the code in the base
class's constructor executing first but this is not what's actually
happening.

(2) Whenever a new object is instantiated, the compiler generates the
IL instruction 'newobj' which allocates memory for the object on the
heap and also calls the constructor (default or the one provided by
us). The default constructor DOESNOT initialize default values unless
we've specified any (like private int a = 5 for ex). If we have
specified default values, first these specified values are assigned to
our members, and then the base constructor is called, on returning,
our derive class constructor body continues execution.

Exact sequence for a chain of base/derived classes during object
creation:

1. Allocate memory for all base/derived members on heap with default
values (0s for ints, false for bools etc).
2. Call the derived class constructor. At the beginning of our class's
constructor, initial values if any are assigned.
3. Our constructor then calls the immediate base class's constructor.
4. Same procedure follows in our base constructor, initial values (if
any specified) are assigned to base class members, and its immediate
base class constructor is called, this procedure follows finally
resulting in a call to System.Object's constructor which does nothing.
5. On completion of the base constructors execution and intializing of
any "specified" member values, control is finally returned back to our
derived class constructor which continues execution from where it
left.
6. If we don't specify any contructor, the default constructor does
the above. Any code we write in our own constructor contains the above
steps which is implicitly generated by the compiler and our own
constructor code.

(3) Default values are assigned to our object members (and its
inherited members) at the time of object creation before our
constructors are called. How did Jon Skeet came to the conclusion
about the exact sequence in which the base/derived members get
initialized? There's nothing specified in the IL other than
'newobj' .... initializing

(4) For structures, when we create a new type, Unlike the heap, values
on the stack are not initialized by default, so the compiler has to
generate code to initialize values for our structure. It does this by
generating the IL instruction 'initobj' which zeroes out the structure
members. Alternately, we can provide our own constructor and in this
we MUST initialize all members otherwise the code wont compile. This
constructor is then simply called by the 'CALL' IL instruction.


Comments are welcomed.

Regards

Joel
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top