468,738 Members | 1,542 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,738 developers. It's quick & easy.

struct member initialization - member by member?!

Hi

I discovered that if you declare a structure (and not 'new()' it) you
can then separately initialize its members and the compiler counts
those separate statements as a full initialization. That struck me as
a bit odd really as I would have thought it would have only bothered
about 'tracking' an 'atomic'/'complete' (via 'new()') initialization
not doing it 'bit by it'!!! Any comments? Seems a bit of an overhead
tracking memberwise initialization doesn't it? Any C# compiler people
out there?

Hoping for some comments to show me that this isn't such a weird thing
please.

Emma Middlebrook
em**************@fastmail.fm

struct Value
{
public int x;
public int y;
}

Value v2;
v2.x = 6; // v2 can not be used yet as 'unassigned' ...
v2.y = 7; // v2 can now be used as all its parts are initialized.
Nov 15 '05 #1
10 8322
emma middlebrook <em**************@fastmail.fm> wrote:
I discovered that if you declare a structure (and not 'new()' it) you
can then separately initialize its members and the compiler counts
those separate statements as a full initialization. That struck me as
a bit odd really as I would have thought it would have only bothered
about 'tracking' an 'atomic'/'complete' (via 'new()') initialization
not doing it 'bit by it'!!! Any comments? Seems a bit of an overhead
tracking memberwise initialization doesn't it? Any C# compiler people
out there?


Why would it be an overhead? Or rather, why do you care about the
overhead which only exists at *compile* time? I'd rather the compiler
kept track of a few extra things to prevent bugs, if it doesn't take
any extra time at runtime.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet/
If replying to the group, please do not mail me too
Nov 15 '05 #2
If you go through the documentation and specs.. you'll see that it says
'structs that are not initilized cannot be accessed or used'. This
doesn't imply that the runtime would do any sort of tracking, in fact,
the compiler will plainly give you a message that there's an error and
won't compile (till you've initialized struct data before using it).
So.. it only checks for validity upon struct data being accessed. Have a
look at the following sample program:

public struct Point
{
public int x, y;

public Point(int p1, int p2)
{
x = p1;
y = p2;
}
}

class MyClass {
static void Main(string args[]) {
Point p;
Console.WriteLine("X is: {0}", p.x);

// Compiler will perform a check hede and will abort..

p.x;
Console.WriteLine("X is: {0}", p.x);

/*
if you comment out the preceding statement, the program will work and
compile. Notice I didn't initialize y and it still worked. This shows
that the compiler doesn't check for 'every' field that's not initialized
but only when a field is being accessed */

}
}
-Andre

emma middlebrook wrote:
Hi

I discovered that if you declare a structure (and not 'new()' it) you
can then separately initialize its members and the compiler counts
those separate statements as a full initialization. That struck me as
a bit odd really as I would have thought it would have only bothered
about 'tracking' an 'atomic'/'complete' (via 'new()') initialization
not doing it 'bit by it'!!! Any comments? Seems a bit of an overhead
tracking memberwise initialization doesn't it? Any C# compiler people
out there?

Hoping for some comments to show me that this isn't such a weird thing
please.

Emma Middlebrook
em**************@fastmail.fm

struct Value
{
public int x;
public int y;
}

Value v2;
v2.x = 6; // v2 can not be used yet as 'unassigned' ...
v2.y = 7; // v2 can now be used as all its parts are initialized.


Nov 15 '05 #3
Exactly - another good point made :)

-Andre

Jon Skeet wrote:
emma middlebrook <em**************@fastmail.fm> wrote:
I discovered that if you declare a structure (and not 'new()' it) you
can then separately initialize its members and the compiler counts
those separate statements as a full initialization. That struck me as
a bit odd really as I would have thought it would have only bothered
about 'tracking' an 'atomic'/'complete' (via 'new()') initialization
not doing it 'bit by it'!!! Any comments? Seems a bit of an overhead
tracking memberwise initialization doesn't it? Any C# compiler people
out there?

Why would it be an overhead? Or rather, why do you care about the
overhead which only exists at *compile* time? I'd rather the compiler
kept track of a few extra things to prevent bugs, if it doesn't take
any extra time at runtime.


Nov 15 '05 #4
Another reason is that structs don't have inheritance and are allocated on
the stack (until they're boxed at which time they get copied onto the heap).
When they're on the stack, they can really be though of as just a grouping
of nested locals on the stack. Until you box them or pass them to some
other method the compiler treats them as such and allows each member to be
independently initialized and used accordingly. This allows methods to
dynamically initialize certain members based on calculated information,
rather than requiring heavy handed stuff like forcing you to zero initialize
everything and then overwrite that with the real value later (plus it
prevents you from accessing the member before the 'real value' has been
set). Now when you pass that struct to some other method or cause it to be
boxed, the method being called has the implicit contract that input
parameters are fully initialized, and so at that point the compiler requires
that all members have been initialized. A similar statement is true for
boxing.

--
--Grant
This posting is provided "AS IS" with no warranties, and confers no rights.
"emma middlebrook" <em**************@fastmail.fm> wrote in message
news:e2**************************@posting.google.c om...
Hi

I discovered that if you declare a structure (and not 'new()' it) you
can then separately initialize its members and the compiler counts
those separate statements as a full initialization. That struck me as
a bit odd really as I would have thought it would have only bothered
about 'tracking' an 'atomic'/'complete' (via 'new()') initialization
not doing it 'bit by it'!!! Any comments? Seems a bit of an overhead
tracking memberwise initialization doesn't it? Any C# compiler people
out there?

Hoping for some comments to show me that this isn't such a weird thing
please.

Emma Middlebrook
em**************@fastmail.fm

struct Value
{
public int x;
public int y;
}

Value v2;
v2.x = 6; // v2 can not be used yet as 'unassigned' ...
v2.y = 7; // v2 can now be used as all its parts are initialized.

Nov 15 '05 #5
100
Hi Grant,

"> Another reason is that structs don't have inheritance and are allocated
on
the stack (until they're boxed at which time they get copied onto the heap).

Not quite accurate, though. ValuTypes can be created unboxed in the managed
heap as part of an reference type members.
This allows methods to
dynamically initialize certain members based on calculated information,
rather than requiring heavy handed stuff like forcing you to zero initialize everything and then overwrite that with the real value later (plus it
prevents you from accessing the member before the 'real value' has been
set).


In the case of creating value type in managed heap all members of the value
type is guaranteed to be zeroed. which means: reference type is set to null,
scalar to 0 and boolean to false. I this particular case c# will not
complain if you use the value without prior initialization.

To be completely correct it will warn you that you gonna use the default
value of the member.
Now when you pass that struct to some other method or cause it to be

B\rgds
100
Nov 15 '05 #6
Jon Skeet <sk***@pobox.com> wrote in message news:<MP************************@news.microsoft.co m>...
emma middlebrook <em**************@fastmail.fm> wrote:
I discovered that if you declare a structure (and not 'new()' it) you
can then separately initialize its members and the compiler counts
those separate statements as a full initialization. That struck me as
a bit odd really as I would have thought it would have only bothered
about 'tracking' an 'atomic'/'complete' (via 'new()') initialization
not doing it 'bit by it'!!! Any comments? Seems a bit of an overhead
tracking memberwise initialization doesn't it? Any C# compiler people
out there?


Why would it be an overhead? Or rather, why do you care about the
overhead which only exists at *compile* time? I'd rather the compiler
kept track of a few extra things to prevent bugs, if it doesn't take
any extra time at runtime.


Why do I care: to broaden my knowledge and better understand what is
happening. I didn't say I was unhappy about any compile-time cost -
just that it seemed surprising.

Thanks

Emma Middlebrook
em**************@fastmail.fm
Nov 15 '05 #7
Andre <fo********@hotmail.com> wrote in message news:<3F**************@hotmail.com>...
If you go through the documentation and specs.. you'll see that it says
'structs that are not initilized cannot be accessed or used'. This
doesn't imply that the runtime would do any sort of tracking, in fact,
the compiler will plainly give you a message that there's an error and
won't compile (till you've initialized struct data before using it).
So.. it only checks for validity upon struct data being accessed. Have a
look at the following sample program:


Who mentioned the run-time tracking anything? Also, as you point out
in your little code snippet, the doc/specs aren't correct if they say
what you quote above - it's possible to use any member of a struct as
long as it's been initialized. As I said, I find it weird that it
allows parts of a partially initialized type to be used. Are you and
Jon both saying you find this quite natural and expected in a language
making quite an effort to stop the programmer shooting themselves in
the foot? It's not a big deal but I was surprised to find that
partially initialized types could be used.

Emma Middlebrook
em**************@fastmail.fm
Nov 15 '05 #8
Andre <fo********@hotmail.com> wrote in message news:<3F**************@hotmail.com>...
If you go through the documentation and specs.. you'll see that it says
'structs that are not initilized cannot be accessed or used'. This
doesn't imply that the runtime would do any sort of tracking, in fact,
the compiler will plainly give you a message that there's an error and
won't compile (till you've initialized struct data before using it).
So.. it only checks for validity upon struct data being accessed. Have a
look at the following sample program:


Who mentioned the run-time tracking anything? Also, as you point out
in your little code snippet, the doc/specs aren't correct if they say
what you quote above - it's possible to use any member of a struct as
long as it's been initialized. As I said, I find it weird that it
allows parts of a partially initialized type to be used. Are you and
Jon both saying you find this quite natural and expected in a language
making quite an effort to stop the programmer shooting themselves in
the foot? It's not a big deal but I was surprised to find that
partially initialized types could be used.

Emma Middlebrook
em**************@fastmail.fm
Nov 15 '05 #9
emma middlebrook <em**************@fastmail.fm> wrote:
Thanks for your reply - I think you have hit on the real nub - I would
like to think of a class/struct as a type that should be either
uninitialized or initialized completely. I don't like this 'weak' idea
of a struct being a loose grouping of members and that its parts can
be used if those parts happened to have been initialized. However, I'm
really glad you mentioned the point that once the struct is passed to
some other method then it has to completely initialized. I'm happy
enough now and have confirmed this to be true both for passing structs
by value and passing structs by reference. This is good news and, to
be honest, I don't care that you can fiddle with the parts and use the
parts 'locally'.


I think it's actually rather helpful that you can fiddle with the parts
locally - you may want to set up one variable based on some
calculations with another, for instance. It would be a pain if you were
forced to use a separate local variable for that.

On the other hand, I'm not entirely sure how this works when the struct
uses properties instead of public fields... I guess you've got to use
"new" in that case.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet/
If replying to the group, please do not mail me too
Nov 15 '05 #10
You are correct on all counts. Thanks for correcting my sloppiness.

One other case where structs can be constructed on the heap: as elements on
an array. In that case also, they are zero initialized.

--
--Grant
This posting is provided "AS IS" with no warranties, and confers no rights.
Nov 15 '05 #11

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

3 posts views Thread by sathyashrayan | last post: by
2 posts views Thread by Immo Birnbaum | last post: by
74 posts views Thread by Zytan | last post: by
6 posts views Thread by Daniel Rudy | last post: by
5 posts views Thread by ssylee | last post: by
1 post views Thread by CARIGAR | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.