Connecting Tech Pros Worldwide Forums | Help | Site Map

struct member initialization - member by member?!

emma middlebrook
Guest
 
Posts: n/a
#1: Nov 15 '05
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
emma_middlebrook@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.

Jon Skeet
Guest
 
Posts: n/a
#2: Nov 15 '05

re: struct member initialization - member by member?!


emma middlebrook <emma_middlebrook@fastmail.fm> wrote:[color=blue]
> 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?[/color]

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 - <skeet@pobox.com>
http://www.pobox.com/~skeet/
If replying to the group, please do not mail me too
Andre
Guest
 
Posts: n/a
#3: Nov 15 '05

re: struct member initialization - member by member?!


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:[color=blue]
> 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
> emma_middlebrook@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.[/color]

Andre
Guest
 
Posts: n/a
#4: Nov 15 '05

re: struct member initialization - member by member?!


Exactly - another good point made :)

-Andre

Jon Skeet wrote:[color=blue]
> emma middlebrook <emma_middlebrook@fastmail.fm> wrote:
>[color=green]
>>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?[/color]
>
>
> 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.
>[/color]

Grant Richins [MS]
Guest
 
Posts: n/a
#5: Nov 15 '05

re: struct member initialization - member by member?!


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" <emma_middlebrook@fastmail.fm> wrote in message
news:e27ae805.0307240012.780b561f@posting.google.c om...[color=blue]
> 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
> emma_middlebrook@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.[/color]


100
Guest
 
Posts: n/a
#6: Nov 15 '05

re: struct member initialization - member by member?!


Hi Grant,

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

Not quite accurate, though. ValuTypes can be created unboxed in the managed
heap as part of an reference type members.
[color=blue]
> This allows methods to
> dynamically initialize certain members based on calculated information,
> rather than requiring heavy handed stuff like forcing you to zero[/color]
initialize[color=blue]
> 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).[/color]

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


emma middlebrook
Guest
 
Posts: n/a
#7: Nov 15 '05

re: struct member initialization - member by member?!


Jon Skeet <skeet@pobox.com> wrote in message news:<MPG.1989abf1f7692bf198a1d3@news.microsoft.co m>...[color=blue]
> emma middlebrook <emma_middlebrook@fastmail.fm> wrote:[color=green]
> > 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?[/color]
>
> 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.[/color]

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
emma_middlebrook@fastmail.fm
emma middlebrook
Guest
 
Posts: n/a
#8: Nov 15 '05

re: struct member initialization - member by member?!


Andre <food_Crazy@hotmail.com> wrote in message news:<3F1FA171.3040206@hotmail.com>...[color=blue]
> 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:[/color]

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
emma_middlebrook@fastmail.fm
emma middlebrook
Guest
 
Posts: n/a
#9: Nov 15 '05

re: struct member initialization - member by member?!


Andre <food_Crazy@hotmail.com> wrote in message news:<3F1FA171.3040206@hotmail.com>...[color=blue]
> 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:[/color]

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
emma_middlebrook@fastmail.fm
Jon Skeet
Guest
 
Posts: n/a
#10: Nov 15 '05

re: struct member initialization - member by member?!


emma middlebrook <emma_middlebrook@fastmail.fm> wrote:[color=blue]
> 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'.[/color]

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 - <skeet@pobox.com>
http://www.pobox.com/~skeet/
If replying to the group, please do not mail me too
Grant Richins [MS]
Guest
 
Posts: n/a
#11: Nov 15 '05

re: struct member initialization - member by member?!


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.


Closed Thread