By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,594 Members | 3,680 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,594 IT Pros & Developers. It's quick & easy.

Structs

P: n/a
Can anyone explain the logic behind structs being allowed neither memeber
initialisers or default constructors.

Doesn't this just encourage developers to create constructors with dummy
arguments?

Thanks in advance,

Jasper Kent.
Nov 16 '05 #1
Share this Question
Share on Google+
19 Replies


P: n/a
IMO:

In C# we come to expect all value types to default to a
zero-initialized instance. So if I wrote:

static void Main(string[] args)
{
int x = new int();
Console.WriteLine(x);

}

and a "2" appeared in the console window, I'd wonder if I regressed to
C++ where such things can occur. The spec guarantees this won't
happen. Since a struct is also a value type, it would be just as
strange to see a "2" appear in the following:

class Class1
{
[STAThread]
static void Main(string[] args)
{
Foo f = new Foo();
Console.WriteLine(f.x);

}
}
struct Foo
{
public int x;
}

To preserve the correct behavior then, a struct cannot explicitly
declare a default constructor, and (as you probably noticed), you
can't use an instance field initializer either.

--
Scott
http://www.OdeToCode.com

On Fri, 30 Apr 2004 13:17:56 +0100, "Jasper Kent"
<ja*********@ntlworld.com> wrote:
Can anyone explain the logic behind structs being allowed neither memeber
initialisers or default constructors.

Doesn't this just encourage developers to create constructors with dummy
arguments?

Thanks in advance,

Jasper Kent.


Nov 16 '05 #2

P: n/a
That's kind of a bootstrap argument, and I don't buy it.

In any O-O language we excpect any type to default to a sensible value.For
exanple:

struct PositiveInteger {...}

....

PositiveInteger val = new PositiveInteger ();

Console.WriteLine (val.ToString ()) ; // We'd be surpsrised by zero here

And anyway, whatever the argument, why is it different for a struct and a
class?

"Scott Allen" <bitmask@[nospam].fred.net> wrote in message
news:6l********************************@4ax.com...
IMO:

In C# we come to expect all value types to default to a
zero-initialized instance. So if I wrote:

static void Main(string[] args)
{
int x = new int();
Console.WriteLine(x);

}

and a "2" appeared in the console window, I'd wonder if I regressed to
C++ where such things can occur. The spec guarantees this won't
happen. Since a struct is also a value type, it would be just as
strange to see a "2" appear in the following:

class Class1
{
[STAThread]
static void Main(string[] args)
{
Foo f = new Foo();
Console.WriteLine(f.x);

}
}
struct Foo
{
public int x;
}

To preserve the correct behavior then, a struct cannot explicitly
declare a default constructor, and (as you probably noticed), you
can't use an instance field initializer either.

--
Scott
http://www.OdeToCode.com

On Fri, 30 Apr 2004 13:17:56 +0100, "Jasper Kent"
<ja*********@ntlworld.com> wrote:
Can anyone explain the logic behind structs being allowed neither memeber
initialisers or default constructors.

Doesn't this just encourage developers to create constructors with dummy
arguments?

Thanks in advance,

Jasper Kent.

Nov 16 '05 #3

P: n/a
Jasper Kent wrote:
That's kind of a bootstrap argument, and I don't buy it.

In any O-O language we excpect any type to default to a sensible value.For
exanple:

struct PositiveInteger {...}

...

PositiveInteger val = new PositiveInteger ();

Console.WriteLine (val.ToString ()) ; // We'd be surpsrised by zero here

And anyway, whatever the argument, why is it different for a struct and a
class?
Here's a cut-n-paste from an entry in Stan Lippmann's weblog that I
recently read (thing1 is the first version of MC++, thing2 is the
revised version of MC++):

================================================== ========
Another difference with a value type between thing1 and thing2 is the
removal of support for a default constructor. [It has been explained to
me that this is because there are instances in which the CLR can create
an instance of the value type without invoking the associated default
constructor. That is, the thing1 addition of support of a default
constructor within a value type cannot be guaranteed. Given that absence
of guarantee, it was felt to be better to drop the support altogether
rather than have it be non-deterministic in its application.]

This is not as bad as it might seem because each object of a value type
is zeroed out automatically, so that the members of a local instance are
not undefined. This also meant that in thing1 a default constructor that
simply zeroed out its members was being redundant. The problem is that a
non-trivial default constructor in a thing1 program has no mechanical
mapping to thing2. The code within the constructor will need to be
migrated into a named init function that would then be explicitly
invoked by the user.
================================================== ========

You can read the full entry here:

http://blogs.msdn.com/slippman/archi.../26/80505.aspx


"Scott Allen" <bitmask@[nospam].fred.net> wrote in message
news:6l********************************@4ax.com...
IMO:

In C# we come to expect all value types to default to a
zero-initialized instance. So if I wrote:

static void Main(string[] args)
{
int x = new int();
Console.WriteLine(x);

}

and a "2" appeared in the console window, I'd wonder if I regressed to
C++ where such things can occur. The spec guarantees this won't
happen. Since a struct is also a value type, it would be just as
strange to see a "2" appear in the following:

class Class1
{
[STAThread]
static void Main(string[] args)
{
Foo f = new Foo();
Console.WriteLine(f.x);

}
}
struct Foo
{
public int x;
}

To preserve the correct behavior then, a struct cannot explicitly
declare a default constructor, and (as you probably noticed), you
can't use an instance field initializer either.

--
Scott
http://www.OdeToCode.com

On Fri, 30 Apr 2004 13:17:56 +0100, "Jasper Kent"
<ja*********@ntlworld.com> wrote:

Can anyone explain the logic behind structs being allowed neither memeber
initialisers or default constructors.

Doesn't this just encourage developers to create constructors with dummy
arguments?

Thanks in advance,

Jasper Kent.


--
mikeb
Nov 16 '05 #4

P: n/a
> > In any O-O language we excpect any type to default to a sensible
value.For
exanple:

struct PositiveInteger {...}

PositiveInteger val = new PositiveInteger ();

Console.WriteLine (val.ToString ()) ; // We'd be surpsrised by zero here
And anyway, whatever the argument, why is it different for a struct and a class?


Here's a cut-n-paste from an entry in Stan Lippmann's weblog that I
recently read (thing1 is the first version of MC++, thing2 is the
revised version of MC++):

================================================== ========
Another difference with a value type between thing1 and thing2 is the
removal of support for a default constructor. [It has been explained to
me that this is because there are instances in which the CLR can create
an instance of the value type without invoking the associated default
constructor. That is, the thing1 addition of support of a default
constructor within a value type cannot be guaranteed. Given that absence
of guarantee, it was felt to be better to drop the support altogether
rather than have it be non-deterministic in its application.]
This is not as bad as it might seem because each object of a value type
is zeroed out automatically, so that the members of a local instance are
not undefined. This also meant that in thing1 a default constructor that
simply zeroed out its members was being redundant. The problem is that a
non-trivial default constructor in a thing1 program has no mechanical
mapping to thing2. The code within the constructor will need to be
migrated into a named init function that would then be explicitly
invoked by the user.

Iam not sure what this text is trying to tell use but we can create a struct
without calling a ctor:

Point p;
p.X=100;
p.Y=120;

in this case the compiler enforces that each field is initialized before
first access.

--
cody

[Freeware, Games and Humor]
www.deutronium.de.vu || www.deutronium.tk
Nov 16 '05 #5

P: n/a

"cody" <pl*************************@gmx.de> wrote in message
news:us**************@TK2MSFTNGP11.phx.gbl...
> In any O-O language we excpect any type to default to a sensible value.For > exanple:
>
> struct PositiveInteger {...}
>
> PositiveInteger val = new PositiveInteger ();
>
> Console.WriteLine (val.ToString ()) ; // We'd be surpsrised by zero here >
> And anyway, whatever the argument, why is it different for a struct and a > class?
Here's a cut-n-paste from an entry in Stan Lippmann's weblog that I
recently read (thing1 is the first version of MC++, thing2 is the
revised version of MC++):

================================================== ========
Another difference with a value type between thing1 and thing2 is the
removal of support for a default constructor. [It has been explained to
me that this is because there are instances in which the CLR can create
an instance of the value type without invoking the associated default
constructor. That is, the thing1 addition of support of a default
constructor within a value type cannot be guaranteed. Given that absence
of guarantee, it was felt to be better to drop the support altogether
rather than have it be non-deterministic in its application.]
This is not as bad as it might seem because each object of a value type
is zeroed out automatically, so that the members of a local instance are
not undefined. This also meant that in thing1 a default constructor that
simply zeroed out its members was being redundant. The problem is that a
non-trivial default constructor in a thing1 program has no mechanical
mapping to thing2. The code within the constructor will need to be
migrated into a named init function that would then be explicitly
invoked by the user.

Iam not sure what this text is trying to tell use but we can create a
struct
without calling a ctor:

Point p;
p.X=100;
p.Y=120;

in this case the compiler enforces that each field is initialized before
first access.

Thats actually the point of the text. Structs don't support default
constructors, but instead are created zero'd out. If the compiler decides to
mantain flow information and ensure that you set all variables, thats good
and helpful, but its not strictly nessecery, IIRC.
--
cody

[Freeware, Games and Humor]
www.deutronium.de.vu || www.deutronium.tk

Nov 16 '05 #6

P: n/a
cody wrote:
In any O-O language we excpect any type to default to a sensible
value.For
exanple:

struct PositiveInteger {...}

PositiveInteger val = new PositiveInteger ();

Console.WriteLine (val.ToString ()) ; // We'd be surpsrised by zero
here
And anyway, whatever the argument, why is it different for a struct and
a
class?


Here's a cut-n-paste from an entry in Stan Lippmann's weblog that I
recently read (thing1 is the first version of MC++, thing2 is the
revised version of MC++):

================================================ ==========
Another difference with a value type between thing1 and thing2 is the
removal of support for a default constructor. [It has been explained to
me that this is because there are instances in which the CLR can create
an instance of the value type without invoking the associated default
constructor. That is, the thing1 addition of support of a default
constructor within a value type cannot be guaranteed. Given that absence
of guarantee, it was felt to be better to drop the support altogether
rather than have it be non-deterministic in its application.]
This is not as bad as it might seem because each object of a value type
is zeroed out automatically, so that the members of a local instance are
not undefined. This also meant that in thing1 a default constructor that
simply zeroed out its members was being redundant. The problem is that a
non-trivial default constructor in a thing1 program has no mechanical
mapping to thing2. The code within the constructor will need to be
migrated into a named init function that would then be explicitly
invoked by the user.


Iam not sure what this text is trying to tell use but we can create a struct
without calling a ctor:

Point p;
p.X=100;
p.Y=120;

in this case the compiler enforces that each field is initialized before
first access.


I'm not an very familiar with MC++, but apparently in the current
version it supports specifying a default constructor for value types.
Here's a line taken from the docs on MC++ __value classes:

-----------------------------------
If no default constructor is defined for a __value class, all of its
data members are initialized to zero by default.
-----------------------------------

I believe that Stan is saying in his weblog is that they are removing
support for default constructors on __value classes in MC++ for the
reason he stated (if you have a copy of Whidbey, you could look there to
verify this - I'm even less familiar with MC++ on Whidbey).

Now, why the CLR might not invoke a default constructor for a value type
is another question. I assume it's because the CLR folks didn't see
it as an important feature (Stan mentions that "this is not as bad as it
seems...") and to allow some optimizations, but I'm just guessing.

--
mikeb
Nov 16 '05 #7

P: n/a
> > Iam not sure what this text is trying to tell use but we can create a
struct
without calling a ctor:

Point p;
p.X=100;
p.Y=120;

in this case the compiler enforces that each field is initialized before
first access.
Thats actually the point of the text. Structs don't support default
constructors, but instead are created zero'd out. If the compiler decides

to mantain flow information and ensure that you set all variables, thats good
and helpful, but its not strictly nessecery, IIRC.

I don't believe that fields are zeroed out automatically if you don't call
the ctor.
If so, the line

Point p = new Point();

would zero out all fields twice.

--
cody

[Freeware, Games and Humor]
www.deutronium.de.vu || www.deutronium.tk
Nov 16 '05 #8

P: n/a

"cody" <pl*************************@gmx.de> wrote in message
news:%2***************@TK2MSFTNGP10.phx.gbl...


I don't believe that fields are zeroed out automatically if you don't call
the ctor.
If so, the line

Point p = new Point();

would zero out all fields twice.
A struct is created, generally, in null memory. I'm pretty sure the .NET
memory model ensures that a variable created on the stack retains a zero
value, even if its unassigned. I could be wrong but it would seem unlikely.

The difference in
Point p;

and
Point p = new Point();

is new Point() issues an initobj instruction in IL. That initobj instruction
should zero memory in most case(structs written in other languages may not
zero, AFAICT), however the original structure on the stack should already be
zeroed(someone correct me if I am wrong, I'm pretty sure I'm not though).
Your example does indeed zero twice: once explicitly(during new Point()) and
once implicitly at stack construction. In that case I would expect the JIT
to effectivly remove the initobj instruction whenever it knows that the
initalization is pointless. new Point() would be more valuable when the
value in p has been used. It would clear that value back out.

As a matter of technical fact, I don't believe that its required to init a
struct before use. C# tends to disallow it, however, under assignment
rules(I've run into one situation where it seems to be allowed, which I have
to check on). I think that is more for the purposes of correct, well though
out code more so than it is a problem with the underlying platform.

--
cody

[Freeware, Games and Humor]
www.deutronium.de.vu || www.deutronium.tk

Nov 16 '05 #9

P: n/a
> A struct is created, generally, in null memory. I'm pretty sure the .NET
memory model ensures that a variable created on the stack retains a zero
value, even if its unassigned. I could be wrong but it would seem unlikely.

No. Locals and structs are created on the stack which does *not* contain
zeros, but instead data of previous method invocations.
If a method returns it would have to overwrite the stack with zeros to clean
up, if you want the behavour that every struct is generated in "null
memory".

C# forces you to initialize *every* local variable completely before first
use. In the case of structs a ctor call is not needed if you assign all
fields manually.
The difference in
Point p;

and
Point p = new Point();

is new Point() issues an initobj instruction in IL. That initobj instruction should zero memory in most case(structs written in other languages may not
zero, AFAICT), however the original structure on the stack should already be zeroed(someone correct me if I am wrong, I'm pretty sure I'm not though).
Your example does indeed zero twice: once explicitly(during new Point()) and once implicitly at stack construction. In that case I would expect the JIT
to effectivly remove the initobj instruction whenever it knows that the
initalization is pointless. new Point() would be more valuable when the
value in p has been used. It would clear that value back out.
Think: Would the initobj call would make sense in any circumstance when
structs would already zeroed out a creation time?
As a matter of technical fact, I don't believe that its required to init a
struct before use. C# tends to disallow it, however, under assignment
rules(I've run into one situation where it seems to be allowed, which I have to check on). I think that is more for the purposes of correct, well though out code more so than it is a problem with the underlying platform.


Which situation? I'd like to hear.

--
cody

Freeware Tools, Games and Humour
http://www.deutronium.de.vu || http://www.deutronium.tk
Nov 16 '05 #10

P: n/a
> A struct is created, generally, in null memory. I'm pretty sure the .NET
memory model ensures that a variable created on the stack retains a zero
value, even if its unassigned. I could be wrong but it would seem unlikely.

No. Locals and structs are created on the stack which does *not* contain
zeros, but instead data of previous method invocations.
If a method returns it would have to overwrite the stack with zeros to clean
up, if you want the behavour that every struct is generated in "null
memory".

C# forces you to initialize *every* local variable completely before first
use. In the case of structs a ctor call is not needed if you assign all
fields manually.
The difference in
Point p;

and
Point p = new Point();

is new Point() issues an initobj instruction in IL. That initobj instruction should zero memory in most case(structs written in other languages may not
zero, AFAICT), however the original structure on the stack should already be zeroed(someone correct me if I am wrong, I'm pretty sure I'm not though).
Your example does indeed zero twice: once explicitly(during new Point()) and once implicitly at stack construction. In that case I would expect the JIT
to effectivly remove the initobj instruction whenever it knows that the
initalization is pointless. new Point() would be more valuable when the
value in p has been used. It would clear that value back out.
Think: Would the initobj call would make sense in any circumstance when
structs would already zeroed out a creation time?
As a matter of technical fact, I don't believe that its required to init a
struct before use. C# tends to disallow it, however, under assignment
rules(I've run into one situation where it seems to be allowed, which I have to check on). I think that is more for the purposes of correct, well though out code more so than it is a problem with the underlying platform.


Which situation? I'd like to hear.

--
cody

Freeware Tools, Games and Humour
http://www.deutronium.de.vu || http://www.deutronium.tk
Nov 16 '05 #11

P: n/a
"cody" <no****************@gmx.net> wrote in message
news:uz**************@TK2MSFTNGP11.phx.gbl...
A struct is created, generally, in null memory. I'm pretty sure the .NET
memory model ensures that a variable created on the stack retains a zero
value, even if its unassigned. I could be wrong but it would seem unlikely.

No. Locals and structs are created on the stack which does *not* contain
zeros, but instead data of previous method invocations.
If a method returns it would have to overwrite the stack with zeros to
clean
up, if you want the behavour that every struct is generated in "null
memory".

That is partially incorrect, as was my original statement.

[quote from CIL Partition 1, page 87 of the MSWord version]
A local variable may hold any data type. However, a particular slot shall
be used in a type consistent way (where the type system is the one described
in clause 11.3.2.1). Local variables are initialized to 0 before entry if
the initialize flag for the method is set (see Section 11.2). The address
of an individual local variable may be taken using the ldloca instruction.
[end quote]

Note "Local variables are initialized to 0 before entry if the initalize
flag for the method is set". This shows that variables are initalized to 0
in almost every case(I've *NEVER* seen IL without that flag), and in this
case the C# compiler generates superflous code with the initobj instruction.
So, indeed, there is generally no reason to do this(and, actually, reference
variables will always be null at calltime, both in and outside of valuetypes
on the stack). Other tests have shown that booleans are set to false as
well(I've yet to manage to make it have a different value). I do wonder
about performance here...it seems to me that it would be as or perhaps more
efficient to zero the small local block(which is almost always small) than
it would be to analyze the local block and zero out only select fields. That
does seem odd to me.

Also, this same document virtualizes the stack as a singly linked list,
meaning that there is no apparent explicit requirement for saving stack
frames in any given place or for using a traditional growing stack. While I
do think the current implementation does use that for ease of implementation
reasons, it isn't definite and assuming that a new stack frame would exist
where an old one did will probably be incorrect at some point.
C# forces you to initialize *every* local variable completely before first
use. In the case of structs a ctor call is not needed if you assign all
fields manually.

Yes, but I don't think it has much to do with the underlying system as much
as clean coding. Forcing explicit definition forces you to know what is
assigned(and makes life easier since you don't have to worry about the
differing defaults that can come up). The CLR doesn't require it, its
strictly a convention forced by C#(which also sets the init flag, causing
double zeroing). Also, while this looks like a constructor call, it isn't,
its C# sugar(at least in most cases, I havn't tested valuetypes with default
constructors. C++ should allow this, but it may or may not be consumable by
C#). For a value type, a call instruction is issued to call the constructor,
vs a newobj instruction which is used for a reference type. The entire
purpose of initobj is to initalize to zero\null\0.0\false(although for
pimatives like bool, the C# compiler emits ldc.i4.0 instead of initobj).

Think: Would the initobj call would make sense in any circumstance when
structs would already zeroed out a creation time?
No, but its there, one would hope the JIT would ignore it. This is an
artifiact of the compiler. I would assume the C# compiler flow control
doesn't interlink with the codegen, the compiler doesn't explicitly need to
emit initobj because it sets the local init flag, however instead of
attempting an optimization of tracking variable usage and deciding when to
issue the initobj instruction, the compiler prefers to do a literal(and
simplier) translation of your code and emits the initobj instruction.
However, due to some strange inconsistencies in the runtime, there is a
chance that initobj is needed in the case you are using strange valuetypes.
As a matter of technical fact, I don't believe that its required to init
a
struct before use. C# tends to disallow it, however, under assignment
rules(I've run into one situation where it seems to be allowed, which I have
to check on). I think that is more for the purposes of correct, well

though
out code more so than it is a problem with the underlying platform.


Which situation? I'd like to hear.


There isn't one, per se. It is either 1) a bug in this complier or 2) the
convention is being dropped. Sometime in the near future I'll make an
inquiry about that, but its irrelevent right now.

Now, if you have proof(empirical, anecdotal, or documented) of an error
here, I am quite interested. The docs aren't particularly clear and my
reading may or may not be correct. I am not interested in C++ or x86's
memory or call models however.
--
cody

Freeware Tools, Games and Humour
http://www.deutronium.de.vu || http://www.deutronium.tk

Nov 16 '05 #12

P: n/a
> No, but its there, one would hope the JIT would ignore it. This is an
artifiact of the compiler. I would assume the C# compiler flow control
doesn't interlink with the codegen, the compiler doesn't explicitly need to emit initobj because it sets the local init flag, however instead of
attempting an optimization of tracking variable usage and deciding when to
issue the initobj instruction, the compiler prefers to do a literal(and
simplier) translation of your code and emits the initobj instruction.
However, due to some strange inconsistencies in the runtime, there is a
chance that initobj is needed in the case you are using strange

valuetypes.
What do you mean with strange valuetype?

--
cody

[Freeware, Games and Humor]
www.deutronium.de.vu || www.deutronium.tk
Nov 16 '05 #13

P: n/a

"cody" <pl*************************@gmx.de> wrote in message
news:uK**************@TK2MSFTNGP12.phx.gbl...
No, but its there, one would hope the JIT would ignore it. This is an
artifiact of the compiler. I would assume the C# compiler flow control
doesn't interlink with the codegen, the compiler doesn't explicitly need to
emit initobj because it sets the local init flag, however instead of
attempting an optimization of tracking variable usage and deciding when
to
issue the initobj instruction, the compiler prefers to do a literal(and
simplier) translation of your code and emits the initobj instruction.
However, due to some strange inconsistencies in the runtime, there is a
chance that initobj is needed in the case you are using strange

valuetypes.
What do you mean with strange valuetype?


Well, the document doesn't explicitly state that it zeroes byte or IntPtr,
so that may be an issue. Also, treatment of enums, DateTime or other system
provided value types aren't explicitly defined. One would assume that the
fields are treated as any other value is, but I don't want to explicitly
state that they behave one way without being able to find definite
documentation.

It also covers any value type with unique charactersitics that I'm not
thinking of or don't know of. Things like TypedReference or Nullable<T> in
2.0 may or may not have special behaviour\treament that I don't know
of(those are just examples of value types that could potentially have
different behavior at the language or runtime level, I doubt they have any
particular special behavior but I don't know.). While its nice to assume
there are no edge cases, until I find documentation(or a knowledgable member
of the design team) that can say there aren't, I don't want to make that
assumption.

Hence, strange value types. Valuetypes that don't behave like others.
Whether they exist or not is difficult to say...they may or may not today
and they may or may not someday. If one exists now...I wouldn't even be
comfortable saying that it'll exist in the next framework. If one exists, it
may well be entirely invisible to user mode code as well, making it
literally undectable without digging through the source of the CLR. Its just
too transient and implementation specific, I think, but its a minor case I
would worry about if I was writing a paper on this issue.
--
cody

[Freeware, Games and Humor]
www.deutronium.de.vu || www.deutronium.tk

Nov 16 '05 #14

P: n/a
Daniel,
Note "Local variables are initialized to 0 before entry if the initalize
flag for the method is set". This shows that variables are initalized to 0
in almost every case(I've *NEVER* seen IL without that flag), and in this
case the C# compiler generates superflous code with the initobj instruction.


If you compile with /unsafe, no methods have the initlocals flag.

Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Nov 16 '05 #15

P: n/a

"Mattias Sjögren" <ma********************@mvps.org> wrote in message
news:uz**************@TK2MSFTNGP12.phx.gbl...
Daniel,
Note "Local variables are initialized to 0 before entry if the initalize
flag for the method is set". This shows that variables are initalized to 0
in almost every case(I've *NEVER* seen IL without that flag), and in this
case the C# compiler generates superflous code with the initobj
instruction.
If you compile with /unsafe, no methods have the initlocals flag.


Really now, that seems a touch odd. One would think it would only happen in
methods that use unsafe code.

Thanks for the info, thats probably yet another reason to avoid compiling
with /unsafe except when absolutly nessecery.
Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.

Nov 16 '05 #16

P: n/a
> >>Note "Local variables are initialized to 0 before entry if the initalize
flag for the method is set". This shows that variables are initalized to 0in almost every case(I've *NEVER* seen IL without that flag), and in thiscase the C# compiler generates superflous code with the initobj
instruction.
If you compile with /unsafe, no methods have the initlocals flag.


Really now, that seems a touch odd. One would think it would only happen

in methods that use unsafe code.

Thanks for the info, thats probably yet another reason to avoid compiling
with /unsafe except when absolutly nessecery.

C# enforces you to intialialize *all* locals anyway. If his statement is
really true (I'll try it),
compiling with unsafe could lead to higher performance.
But I expect this to be true only in unsafe code blocks, not the entire
assembly.

--
cody

Freeware Tools, Games and Humour
http://www.deutronium.de.vu || http://www.deutronium.tk
Nov 16 '05 #17

P: n/a

"cody" <no****************@gmx.net> wrote in message
news:e0**************@tk2msftngp13.phx.gbl...
>>Note "Local variables are initialized to 0 before entry if the
>>initalize
>>flag for the method is set". This shows that variables are initalized
>>to 0 >>in almost every case(I've *NEVER* seen IL without that flag), and in this >>case the C# compiler generates superflous code with the initobj
>>instruction.
>
> If you compile with /unsafe, no methods have the initlocals flag.
Really now, that seems a touch odd. One would think it would only happen

in
methods that use unsafe code.

Thanks for the info, thats probably yet another reason to avoid compiling
with /unsafe except when absolutly nessecery.

C# enforces you to intialialize *all* locals anyway. If his statement is
really true (I'll try it),
compiling with unsafe could lead to higher performance.


I wouldn't count on it. The JIT is a factor here that you are ignoring. It
should be capable of detecting useless assignments like that. Beyond that,
the assignment time should be less than a fraction of a percent of execution
time. Even if unsafe changes performance, I think it'd be so utterly
indetectable, it would be entirely wasteful to do so. There is a chance that
if the JIT catches the situation where this code may be slower, if
initalization at call frame build time is faster than at runtime during
instruction execution.

I'm looking forward to your results.
But I expect this to be true only in unsafe code blocks, not the entire
assembly.
--
cody

Freeware Tools, Games and Humour
http://www.deutronium.de.vu || http://www.deutronium.tk

Nov 16 '05 #18

P: n/a
> > C# enforces you to intialialize *all* locals anyway. If his statement is
really true (I'll try it),
compiling with unsafe could lead to higher performance.
I wouldn't count on it. The JIT is a factor here that you are ignoring. It
should be capable of detecting useless assignments like that. Beyond that,
the assignment time should be less than a fraction of a percent of

execution time. Even if unsafe changes performance, I think it'd be so utterly
indetectable, it would be entirely wasteful to do so. There is a chance that if the JIT catches the situation where this code may be slower, if
initalization at call frame build time is faster than at runtime during
instruction execution.

I'm looking forward to your results.

I now tried it and that are my results:

unsafe long Test()
{
long a=0;
long b=0;
long c=0;
long d=0;
long e=0;
long f=0;
long g=0;
long h=0;
return a+b+c+d+e+f+g+h;
}

// release, no ide 0,8692856
// debug, no ide 0,8926981
// release, ide 5,033917
// debug, ide 5,515041

safe or unsafe appeared to change nothing. but I found running the app
outside the ide was 5,5 times faster.
the release mode was always slightly fast than debug mode in both ide and
without ide.

So I do not believe that the unsafe modifier affects initialisation of
variables.

--
cody

[Freeware, Games and Humor]
www.deutronium.de.vu || www.deutronium.tk
Nov 16 '05 #19

P: n/a

"cody" <pl*************************@gmx.de> wrote in message
news:u0**************@tk2msftngp13.phx.gbl...
> C# enforces you to intialialize *all* locals anyway. If his statement
> is
> really true (I'll try it),
> compiling with unsafe could lead to higher performance.
I wouldn't count on it. The JIT is a factor here that you are ignoring.
It
should be capable of detecting useless assignments like that. Beyond
that,
the assignment time should be less than a fraction of a percent of

execution
time. Even if unsafe changes performance, I think it'd be so utterly
indetectable, it would be entirely wasteful to do so. There is a chance

that
if the JIT catches the situation where this code may be slower, if
initalization at call frame build time is faster than at runtime during
instruction execution.

I'm looking forward to your results.

I now tried it and that are my results:

unsafe long Test()
{
long a=0;
long b=0;
long c=0;
long d=0;
long e=0;
long f=0;
long g=0;
long h=0;
return a+b+c+d+e+f+g+h;
}

// release, no ide 0,8692856
// debug, no ide 0,8926981
// release, ide 5,033917
// debug, ide 5,515041

safe or unsafe appeared to change nothing. but I found running the app
outside the ide was 5,5 times faster.
the release mode was always slightly fast than debug mode in both ide and
without ide.

So I do not believe that the unsafe modifier affects initialisation of
variables.


About what I expected. Even if the init flag isn't set, I'm pretty sure the
JIT would equalize the two situations. And, as I've said, if not, its
probably not significant enough to matter.
--
cody

[Freeware, Games and Humor]
www.deutronium.de.vu || www.deutronium.tk

Nov 16 '05 #20

This discussion thread is closed

Replies have been disabled for this discussion.