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

I think C# is forcing us to write more (redundant) code

P: n/a
I think C# is forcing us to write more code by enforcing a rule that can be
summarized as 'A local variable must be assgined *explicitly* before reading
its value.'

If you are interested in what I mean, please look at this feedback my me:

http://lab.msdn.microsoft.com/produc...2-d266472a84ac

If you think I am right, please vote for this feedback.

Thanks.

Nov 17 '05 #1
Share this Question
Share on Google+
40 Replies


P: n/a
Neo The One wrote:
I think C# is forcing us to write more code by enforcing a rule that can be
summarized as 'A local variable must be assgined *explicitly* before reading
its value.'

If you are interested in what I mean, please look at this feedback my me:

http://lab.msdn.microsoft.com/produc...2-d266472a84ac

If you think I am right, please vote for this feedback.

Thanks.


Since the local variables are not guaranteed to be initialized to
anything specific, moving this to a warning will guarantee that there's
a lot of projects that will have strange crashes.

Since .NET has mechanisms built in to make sure data is always valid,
and never inconsistent or corrupted (hence the need to initialize local
variables), a warning will never be enough as a warning can be ignored,
with unforseen consequences.

The effect on the garbage collector if you start to treat random memory
adresses as .NET objects is probably the main reason for this.

So yes, I voted, but I voted 1.

If you want a change to the .NET compilers, you should add a suggestion
that all local variables are zeroed out instead.
Nov 17 '05 #2

P: n/a
I think my English is not good enough to explain what I have found.

Please compare the C# code and VB code and their IL code in the attachment
file. You will see that VB safely compares an unintialized (not explicitly
assigned) string variable with Nothing. I don't think this will cause crashes
and that's what the VB language specifies that local variables have default
values:

<quote from="ms-help://MS.NETFrameworkSDKv1.1/vblr7net/html/vastmDim.htm">
If you do not specify an initialization value for a variable, Visual Basic
initializes it to the default value for its data type. The default
initialization values are as follows:

0 for all numeric types (including Byte).
Binary 0 for Char.
Nothing for all reference types (including Object, String, and all arrays).
False for Boolean.
12:00 AM of January 1 of the year 1 for Date.
Each element of a structure or array is initialized as if it were a separate
variable
</quote>

That is to say VB compiler guarantees that all variables have default
values. But from the IL code, I cannot see an explicit assignment of "s" to
Nothing. That proves that the underlying Common Object Runtime (COR) has a
mechanism to have all local variables (and other variables) have default
values.

If the above facts are true, then C# compiler is generating REDUNDANT code...

Hope I have made my understandings clear.
"Lasse Vågsæther Karlsen" wrote:
Neo The One wrote:
I think C# is forcing us to write more code by enforcing a rule that can be
summarized as 'A local variable must be assgined *explicitly* before reading
its value.'

If you are interested in what I mean, please look at this feedback my me:

http://lab.msdn.microsoft.com/produc...2-d266472a84ac

If you think I am right, please vote for this feedback.

Thanks.


Since the local variables are not guaranteed to be initialized to
anything specific, moving this to a warning will guarantee that there's
a lot of projects that will have strange crashes.

Since .NET has mechanisms built in to make sure data is always valid,
and never inconsistent or corrupted (hence the need to initialize local
variables), a warning will never be enough as a warning can be ignored,
with unforseen consequences.

The effect on the garbage collector if you start to treat random memory
adresses as .NET objects is probably the main reason for this.

So yes, I voted, but I voted 1.

If you want a change to the .NET compilers, you should add a suggestion
that all local variables are zeroed out instead.

Nov 17 '05 #3

P: n/a
Creation and assignment of variables is essentially the same for VB and C#.
Value types are assigned their normal default values. For example you don't
have to explicitly write:

int x = new int(12);

and if you just use "int x;" then x contains zero.

Reference types are assigned null by the framework too.

--
Bob Powell [MVP]
Visual C#, System.Drawing

Ramuseco Limited .NET consulting
http://www.ramuseco.com

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.

"Neo The One" <Ne*******@discussions.microsoft.com> wrote in message
news:94**********************************@microsof t.com...
I think my English is not good enough to explain what I have found.

Please compare the C# code and VB code and their IL code in the attachment
file. You will see that VB safely compares an unintialized (not explicitly
assigned) string variable with Nothing. I don't think this will cause
crashes
and that's what the VB language specifies that local variables have
default
values:

<quote from="ms-help://MS.NETFrameworkSDKv1.1/vblr7net/html/vastmDim.htm">
If you do not specify an initialization value for a variable, Visual Basic
initializes it to the default value for its data type. The default
initialization values are as follows:

0 for all numeric types (including Byte).
Binary 0 for Char.
Nothing for all reference types (including Object, String, and all
arrays).
False for Boolean.
12:00 AM of January 1 of the year 1 for Date.
Each element of a structure or array is initialized as if it were a
separate
variable
</quote>

That is to say VB compiler guarantees that all variables have default
values. But from the IL code, I cannot see an explicit assignment of "s"
to
Nothing. That proves that the underlying Common Object Runtime (COR) has
a
mechanism to have all local variables (and other variables) have default
values.

If the above facts are true, then C# compiler is generating REDUNDANT
code...

Hope I have made my understandings clear.
"Lasse Vgsther Karlsen" wrote:
Neo The One wrote:
> I think C# is forcing us to write more code by enforcing a rule that
> can be
> summarized as 'A local variable must be assgined *explicitly* before
> reading
> its value.'
>
> If you are interested in what I mean, please look at this feedback my
> me:
>
> http://lab.msdn.microsoft.com/produc...2-d266472a84ac
>
> If you think I am right, please vote for this feedback.
>
> Thanks.
>


Since the local variables are not guaranteed to be initialized to
anything specific, moving this to a warning will guarantee that there's
a lot of projects that will have strange crashes.

Since .NET has mechanisms built in to make sure data is always valid,
and never inconsistent or corrupted (hence the need to initialize local
variables), a warning will never be enough as a warning can be ignored,
with unforseen consequences.

The effect on the garbage collector if you start to treat random memory
adresses as .NET objects is probably the main reason for this.

So yes, I voted, but I voted 1.

If you want a change to the .NET compilers, you should add a suggestion
that all local variables are zeroed out instead.

Nov 17 '05 #4

P: n/a

"Neo The One" <Ne*******@discussions.microsoft.com> wrote in message
news:86**********************************@microsof t.com...
I think C# is forcing us to write more code by enforcing a rule that can be
summarized as 'A local variable must be assgined *explicitly* before
reading
its value.'

If you are interested in what I mean, please look at this feedback my me:

http://lab.msdn.microsoft.com/produc...2-d266472a84ac

If you think I am right, please vote for this feedback.

Thanks.


Both C# and VB do not initialize local variables (as shown by the IL). The
only difference is that the current version of VB does not flag following as
an error.

Dim s As String
Try
s = "test"
Finally
If s Is Nothing Then
...
End If
End Try
....

but it is an error, and that's been corrected in the next version, where:

If s Is Nothing Then ...

Results in a compiler message:
warning BC42104: Variable 's' is used before it has been assigned a value
A null reference exception could result at runtime.

Note that it throws a Warning not an Error, that means that VB is more
restrictive than C#.
The runtime does initialize locals as your other post suggest.

Willy.



Nov 17 '05 #5

P: n/a
How do you understand this quote from
ms-help://MS.VSCC.2003/MS.MSDNQTR.2005JUL.1033/vblr7/html/vastmDim.htm:

If you do not specify an initialization value for a variable, Visual Basic
initializes it to the default value for its data type. The default
initialization values are as follows:

0 for all numeric types (including Byte).
Binary 0 for Char.
Nothing for all reference types (including Object, String, and all arrays).
False for Boolean.
12:00 AM of January 1 of the year 1 for Date.
Each element of a structure or array is initialized as if it were a separate
variable.

"Willy Denoyette [MVP]" wrote:

"Neo The One" <Ne*******@discussions.microsoft.com> wrote in message
news:86**********************************@microsof t.com...
I think C# is forcing us to write more code by enforcing a rule that can be
summarized as 'A local variable must be assgined *explicitly* before
reading
its value.'

If you are interested in what I mean, please look at this feedback my me:

http://lab.msdn.microsoft.com/produc...2-d266472a84ac

If you think I am right, please vote for this feedback.

Thanks.


Both C# and VB do not initialize local variables (as shown by the IL). The
only difference is that the current version of VB does not flag following as
an error.

Dim s As String
Try
s = "test"
Finally
If s Is Nothing Then
...
End If
End Try
....

but it is an error, and that's been corrected in the next version, where:

If s Is Nothing Then ...

Results in a compiler message:
warning BC42104: Variable 's' is used before it has been assigned a value
A null reference exception could result at runtime.

Note that it throws a Warning not an Error, that means that VB is more
restrictive than C#.
The runtime does initialize locals as your other post suggest.

Willy.



Nov 17 '05 #6

P: n/a

"Neo The One" <Ne*******@discussions.microsoft.com> wrote in message
news:B4**********************************@microsof t.com...
How do you understand this quote from
ms-help://MS.VSCC.2003/MS.MSDNQTR.2005JUL.1033/vblr7/html/vastmDim.htm:

If you do not specify an initialization value for a variable, Visual Basic
initializes it to the default value for its data type. The default
initialization values are as follows:

0 for all numeric types (including Byte).
Binary 0 for Char.
Nothing for all reference types (including Object, String, and all
arrays).
False for Boolean.
12:00 AM of January 1 of the year 1 for Date.
Each element of a structure or array is initialized as if it were a
separate
variable.

"Willy Denoyette [MVP]" wrote:

"Neo The One" <Ne*******@discussions.microsoft.com> wrote in message
news:86**********************************@microsof t.com...
>I think C# is forcing us to write more code by enforcing a rule that can
>be
> summarized as 'A local variable must be assgined *explicitly* before
> reading
> its value.'
>
> If you are interested in what I mean, please look at this feedback my
> me:
>
> http://lab.msdn.microsoft.com/produc...2-d266472a84ac
>
> If you think I am right, please vote for this feedback.
>
> Thanks.
>


Both C# and VB do not initialize local variables (as shown by the IL).
The
only difference is that the current version of VB does not flag following
as
an error.

Dim s As String
Try
s = "test"
Finally
If s Is Nothing Then
...
End If
End Try
....

but it is an error, and that's been corrected in the next version, where:

If s Is Nothing Then ...

Results in a compiler message:
warning BC42104: Variable 's' is used before it has been assigned a value
A null reference exception could result at runtime.

Note that it throws a Warning not an Error, that means that VB is more
restrictive than C#.
The runtime does initialize locals as your other post suggest.

Willy.


Sorry, this last sentence is wrong, it's the JIT generated native code that
initializes the locals to 0.
So depending on their type all values have their bits set to 0, like an
Integer and an object reference = 0x00000000, a byte is set to 0x00, a char
= 0x0000 etc...

So, at the IL level, it might look like the explicit assignment of the
default value for the type, as required by C# is redundant, but at the
native code level all is the same. The only difference is that C# is more
restrictive than VB, and that's a choice made by the C# language team. Maybe
they could relax this and issue a warning instead of an error just like VB,
but AFAIK I prefer clean compiles without warnings at all.

Willy.
Nov 17 '05 #7

P: n/a

"Neo The One" <Ne*******@discussions.microsoft.com> wrote in message
news:94**********************************@microsof t.com...
That is to say VB compiler guarantees that all variables have default
values. But from the IL code, I cannot see an explicit assignment of "s"
to
Nothing. That proves that the underlying Common Object Runtime (COR) has
a
mechanism to have all local variables (and other variables) have default
values.
First off, it's CIL (Common Intremediate Language), not IL. And CLR (Common
Language Runtime), not COR.
I think you look to much at C#, VB and CIL and not what the JITter does and
the actual running code.
If the above facts are true, then C# compiler is generating REDUNDANT
code...
The JITer will decide if a local 32-bit will be on stack or in register.
However, managed code will ensure that you don't use garbage values in
registers or on stack.

If you ever coded in C, C++ or Delphi, you must agree that this is The Good
Thing.
I can't even begin to count all the bugs I have written over the years due
to a rough unitialized pointer. My Bad!
Hope I have made my understandings clear.


Yes you have, but the CIL is unimportant. It's what the JITter does with it
that counts.

Happy Coding
- Michael S
Nov 17 '05 #8

P: n/a
Well, have a look at those values. Do you see a pattern?
All it does is to fill the allocated space with zeroes. Nothing new here.

Happy Coding
- Michael S

"Neo The One" <Ne*******@discussions.microsoft.com> wrote in message
news:B4**********************************@microsof t.com...
How do you understand this quote from
ms-help://MS.VSCC.2003/MS.MSDNQTR.2005JUL.1033/vblr7/html/vastmDim.htm:

If you do not specify an initialization value for a variable, Visual Basic
initializes it to the default value for its data type. The default
initialization values are as follows:

0 for all numeric types (including Byte).
Binary 0 for Char.
Nothing for all reference types (including Object, String, and all
arrays).
False for Boolean.
12:00 AM of January 1 of the year 1 for Date.
Each element of a structure or array is initialized as if it were a
separate
variable.

"Willy Denoyette [MVP]" wrote:

"Neo The One" <Ne*******@discussions.microsoft.com> wrote in message
news:86**********************************@microsof t.com...
>I think C# is forcing us to write more code by enforcing a rule that can
>be
> summarized as 'A local variable must be assgined *explicitly* before
> reading
> its value.'
>
> If you are interested in what I mean, please look at this feedback my
> me:
>
> http://lab.msdn.microsoft.com/produc...2-d266472a84ac
>
> If you think I am right, please vote for this feedback.
>
> Thanks.
>


Both C# and VB do not initialize local variables (as shown by the IL).
The
only difference is that the current version of VB does not flag following
as
an error.

Dim s As String
Try
s = "test"
Finally
If s Is Nothing Then
...
End If
End Try
....

but it is an error, and that's been corrected in the next version, where:

If s Is Nothing Then ...

Results in a compiler message:
warning BC42104: Variable 's' is used before it has been assigned a value
A null reference exception could result at runtime.

Note that it throws a Warning not an Error, that means that VB is more
restrictive than C#.
The runtime does initialize locals as your other post suggest.

Willy.



Nov 17 '05 #9

P: n/a

"Willy Denoyette [MVP]" <wi*************@telenet.be> wrote in message
news:uW*************@tk2msftngp13.phx.gbl...
So, at the IL level, it might look like the explicit assignment of the
default value for the type, as required by C# is redundant, but at the
native code level all is the same. The only difference is that C# is more
restrictive than VB, and that's a choice made by the C# language team.
Maybe they could relax this and issue a warning instead of an error just
like VB, but AFAIK I prefer clean compiles without warnings at all.

Willy.


You explained this much better than me.
I consider this restriction in C# a virtue and not a flaw. And I think you
do to.

Happy Initializing
- Michael S
Nov 17 '05 #10

P: n/a
I, too, disagree with this suggestion.

VB and C# come at programming from two different directions, and tend
to appeal to different kinds of programmers. I prefer C# because
everything from the language structure to the compiler prods you to
think more about what you're doing and why. Of course, a language and a
compiler can't stop you from being sloppy and muddled, but at least C#
insists that you state what you want clearly. It tends to appeal to
methodical, pedantic sorts like me, who don't mind spending an extra
day or two on a project if it comes out a more solid app as a result.

VB, on the other hand, is the classic
macro-language-turned-serious-programming-language: it tries to do as
much as possible for you, and bug you as little as possible. It appeals
to the "I can prototype that app in thirty minutes" crowd, who love RAD
because it starts with the word "rapid." VB tries to do a lot for you,
even if what it does is occasionally not what you wanted.

This suggestion, to me, is just complaining that C# is not enough like
VB. While each language certainly contains ideas that could be useful
in the other, this, IMHO, isn't one of them.

Nov 17 '05 #11

P: n/a

"Michael S" <a@b.c> wrote in message
news:%2****************@TK2MSFTNGP09.phx.gbl...

"Willy Denoyette [MVP]" <wi*************@telenet.be> wrote in message
news:uW*************@tk2msftngp13.phx.gbl...
So, at the IL level, it might look like the explicit assignment of the
default value for the type, as required by C# is redundant, but at the
native code level all is the same. The only difference is that C# is more
restrictive than VB, and that's a choice made by the C# language team.
Maybe they could relax this and issue a warning instead of an error just
like VB, but AFAIK I prefer clean compiles without warnings at all.

Willy.


You explained this much better than me.
I consider this restriction in C# a virtue and not a flaw. And I think you
do to.

Happy Initializing
- Michael S


Yes, IMO C# made the right choice here, they can (but I doubt they ever
will) relax the requirement and generate a warning instead of an error. The
VB team could not go back and issue an error without breaking the compiles,
that's why they just throw a warning in VS2005.

Willy.
Nov 17 '05 #12

P: n/a
Bob Powell [MVP] <bob@_spamkiller_bobpowell.net> wrote:
Creation and assignment of variables is essentially the same for VB and C#.
Value types are assigned their normal default values. For example you don't
have to explicitly write:

int x = new int(12);

and if you just use "int x;" then x contains zero.

Reference types are assigned null by the framework too.


No, that's not true for local variables. Local variables aren't
assigned to anything by default, and can't be read until they've been
definitely assigned.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 17 '05 #13

P: n/a

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Bob Powell [MVP] <bob@_spamkiller_bobpowell.net> wrote:
Creation and assignment of variables is essentially the same for VB and
C#.
Value types are assigned their normal default values. For example you
don't
have to explicitly write:

int x = new int(12);

and if you just use "int x;" then x contains zero.

Reference types are assigned null by the framework too.


No, that's not true for local variables. Local variables aren't
assigned to anything by default, and can't be read until they've been
definitely assigned.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too


Actualy they are, the IL directive .locals init, emitted by C# , VB.NET and
ME C++, is a hint for the JIT to initialize the locals (stack as well as
register allocated) to 0 (zero).
Willy.
Nov 17 '05 #14

P: n/a
Willy Denoyette [MVP] <wi*************@telenet.be> wrote:
No, that's not true for local variables. Local variables aren't
assigned to anything by default, and can't be read until they've been
definitely assigned.


Actualy they are, the IL directive .locals init, emitted by C# , VB.NET and
ME C++, is a hint for the JIT to initialize the locals (stack as well as
register allocated) to 0 (zero).


That may be true of the implementation, but not of the specification. I
should have made that clearer - it's actually important when it comes
to calling methods with "out" parameters written in other languages,
but within C# the value is effectively unspecified. This is perhaps
unfortunate...

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 17 '05 #15

P: n/a

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Willy Denoyette [MVP] <wi*************@telenet.be> wrote:
> No, that's not true for local variables. Local variables aren't
> assigned to anything by default, and can't be read until they've been
> definitely assigned.


Actualy they are, the IL directive .locals init, emitted by C# , VB.NET
and
ME C++, is a hint for the JIT to initialize the locals (stack as well as
register allocated) to 0 (zero).


That may be true of the implementation, but not of the specification. I
should have made that clearer - it's actually important when it comes
to calling methods with "out" parameters written in other languages,
but within C# the value is effectively unspecified. This is perhaps
unfortunate...

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too


Mind to tell us what specification are you talking about?
To me it's clear that C#, J#, C++ and VB.NET compilers emits a '.locals
init' directive and as a result the locals are initialized to zero. Sure,
the locals are not explicitely initialized (as per specification?), but all
(MS) compilers do emit the .local init directive in the method header,
question is based on what specification.
Not sure what 'out' parameters have to do with this, though, the callee
does/should not consider an out argument being 'initialized' by the caller,
the value it as doesn't matter anyway.
Willy.

Nov 17 '05 #16

P: n/a

"Willy Denoyette [MVP]" <wi*************@telenet.be> wrote in message
news:uP**************@TK2MSFTNGP09.phx.gbl...

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Willy Denoyette [MVP] <wi*************@telenet.be> wrote:
> No, that's not true for local variables. Local variables aren't
> assigned to anything by default, and can't be read until they've been
> definitely assigned.

Actualy they are, the IL directive .locals init, emitted by C# , VB.NET
and
ME C++, is a hint for the JIT to initialize the locals (stack as well as
register allocated) to 0 (zero).


That may be true of the implementation, but not of the specification. I
should have made that clearer - it's actually important when it comes
to calling methods with "out" parameters written in other languages,
but within C# the value is effectively unspecified. This is perhaps
unfortunate...

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too


Mind to tell us what specification are you talking about?
To me it's clear that C#, J#, C++ and VB.NET compilers emits a '.locals
init' directive and as a result the locals are initialized to zero. Sure,
the locals are not explicitely initialized (as per specification?), but
all (MS) compilers do emit the .local init directive in the method header,
question is based on what specification.
Not sure what 'out' parameters have to do with this, though, the callee
does/should not consider an out argument being 'initialized' by the
caller, the value it as doesn't matter anyway.
Willy.

I've investigated this somwhat further and found that the JIT doesn't even
care about the .locals directive, it initilizes the locals irrespective the
presence of the init.
This piece of C# code (the same is true for the other languages I mentioned
before):

void Meth1()
{
s = "test";

...
results in:

(// comments added)
00C800A1 xor eax,eax //clear eax
00C800A3 mov dword ptr [ebp-24h],eax //1. move eax into local variable s (s
= 0x00000000)
00C800A6 xor eax,eax
00C800A8 mov dword ptr [ebp-18h],eax
00C800AB mov eax,dword ptr ds:[228303Ch] // move address of string object
"test" (from static heap of this domain) into eax
00C800B1 mov dword ptr [ebp-24h],eax // move eax into local variable s
...
you see that the local s is first initialized to 0 before being assigned,
this add two additional instruction per local variable.

Willy.

Nov 17 '05 #17

P: n/a
After reading all the replies, I think my problem now turns into another
problem:

Does the COR (Common Object Runtime) provide such a mechanism to ensure call
lcoal variables have default values?

If the COR guarantees that, then C# compiler is generating redundant code.
Otherwise, VB compiler is generating WRONG code (as many of you have pointed
out).

Today, I used the ILDasm tool (part of .NET SDK) to examine the IL code
generated both by C# and VB compilers. I found that the Lutz Roeder's
Reflector does not give the 'init' flag. Here is the IL code ILDasm gives me:

..locals init (string V_0)

I guess the init flag(?) tells the COR to initialize all local variables in
the parentheses.

I also tried to read the IL reference (C:\Program
Files\Microsoft.NET\SDK\v1.1\Tool Developers Guide\docs\Partition III
CIL.doc), but that it does not have explanation about .locals instruction.
Does anyone know where can I find a complete reference to IL instructions?

Thanks.
"Neo The One" wrote:
I think C# is forcing us to write more code by enforcing a rule that can be
summarized as 'A local variable must be assgined *explicitly* before reading
its value.'

If you are interested in what I mean, please look at this feedback my me:

http://lab.msdn.microsoft.com/produc...2-d266472a84ac

If you think I am right, please vote for this feedback.

Thanks.

Nov 17 '05 #18

P: n/a
Willy Denoyette [MVP] <wi*************@telenet.be> wrote:
That may be true of the implementation, but not of the specification. I
should have made that clearer - it's actually important when it comes
to calling methods with "out" parameters written in other languages,
but within C# the value is effectively unspecified. This is perhaps
unfortunate...
Mind to tell us what specification are you talking about?


The C# specification (rather than the CLI spec).

From section 12.1.7 (ECMA numbering):

<quote>
A local variable is not automatically initialized and thus has no
default value.
</quote>
To me it's clear that C#, J#, C++ and VB.NET compilers emits a '.locals
init' directive and as a result the locals are initialized to zero. Sure,
the locals are not explicitely initialized (as per specification?), but all
(MS) compilers do emit the .local init directive in the method header,
question is based on what specification.
See above. I believe a C# compiler which actually initialised all local
ints to 1 instead of 0 would still be compliant with the C# spec, for
example.
Not sure what 'out' parameters have to do with this, though, the callee
does/should not consider an out argument being 'initialized' by the caller,
the value it as doesn't matter anyway.


The callee can't see the value in C#, but can in other languages (and
can in C# using RealProxy) - therefore it must be a valid value. For
instance, if it's a reference, it can't be just some arbitrary value.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 17 '05 #19

P: n/a

"Willy Denoyette [MVP]" <wi*************@telenet.be> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
I've investigated this somwhat further and found that the JIT doesn't even
care about the .locals directive, it initilizes the locals irrespective
the presence of the init.


Sorry, compiled the wrong il.
Following code...
{
string s = null; // required by the C compiler
try
{
s = ........;
}

with .locals init (the default) results in :

00C800A1 xor eax,eax
00C800A3 mov dword ptr [ebp-24h],eax //1 - .locals init
00C800A6 xor eax,eax
00C800A8 mov dword ptr [ebp-18h],eax
00C800AB xor edx,edx
00C800AD mov dword ptr [ebp-24h],edx //2 - string s = null;
00C800B0 mov eax,dword ptr ds:[228303Ch]
00C800B6 mov dword ptr [ebp-24h],eax

and this when init is removed from .locals

00C800A3 mov dword ptr [ebp-24h],eax //1 - string s = null;
00C800A6 xor eax,eax
00C800A8 mov dword ptr [ebp-18h],eax
00C800AB xor edx,edx
00C800AD mov dword ptr [ebp-24h],edx
00C800B0 mov eax,dword ptr ds:[228303Ch]

See the superflous initialization of the s reference.

Willy.
Nov 17 '05 #20

P: n/a

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Willy Denoyette [MVP] <wi*************@telenet.be> wrote:
> That may be true of the implementation, but not of the specification. I
> should have made that clearer - it's actually important when it comes
> to calling methods with "out" parameters written in other languages,
> but within C# the value is effectively unspecified. This is perhaps
> unfortunate...


Mind to tell us what specification are you talking about?


The C# specification (rather than the CLI spec).

From section 12.1.7 (ECMA numbering):

<quote>
A local variable is not automatically initialized and thus has no
default value.
</quote>


Which tends to be incorrect, it's the C# compiler that emits the ".locals
init" , right?.
To me it's clear that C#, J#, C++ and VB.NET compilers emits a '.locals
init' directive and as a result the locals are initialized to zero. Sure,
the locals are not explicitely initialized (as per specification?), but
all
(MS) compilers do emit the .local init directive in the method header,
question is based on what specification.


See above. I believe a C# compiler which actually initialised all local
ints to 1 instead of 0 would still be compliant with the C# spec, for
example.

Agreed, any value would do, but according "The C# specification" it's not
initialized at all, which is not true.
Not sure what 'out' parameters have to do with this, though, the callee
does/should not consider an out argument being 'initialized' by the
caller,
the value it as doesn't matter anyway.


The callee can't see the value in C#, but can in other languages (and
can in C# using RealProxy) - therefore it must be a valid value. For
instance, if it's a reference, it can't be just some arbitrary value.


Why not?, 'out' passes the address of the variable, sure the address must be
valid, but the 'value' it points to may contain anything.

consider a ref. type string as local variable.

string s; // no explicit init. required.
F(out s);

the local (a reference) is on the stack (suppose 32 bit windows here) and
implicitely initialized to 0 by '.locals init'.

address value
0x0012b644 0x00000000

'out s' argument passed:
= 0x0012b644

The callee expects a 'valid' pointer to a type string (a ref) and managed
code callees cannot take the value pointed by, they can only assign (this is
compiler enforced).

F(out s)
{
string t = s; // invalid code, C# compiler error
s = "newstring"; //Valid - this sets the 'value' of the variable
pointed to by the arg. to the reference of the string instance.
....
now consider this C# snip:

string s = null; // explicit init. compiler enforced
{
...
F(out s);

The passed arg. is exactly the same..

address value
0x0012b644 0x00000000

'out s' argument passed:
= 0x0012b644

but here the generated machine code contains a superflous inititalization of
s (see my other reply).
I'm not sure what other languages you refer to, all managed languages I know
use the same semantics for out arguments. When calling native C using out
arguments, it's the PInvoke layer who takes care about the marshaling, and
it's up to the callee to know the semantics.

Willy.

Nov 17 '05 #21

P: n/a
[Not sure why my post was lost... So I post it again.]

After reading all the replies, I think my problem now turns into another one:

Does the IL guarantees that all local variables have default values?

I used ILDasm tool (part of SDK) to examine the result IL code and found
that it differs a little with those by Lutz Roeder's Reflector:

..locals init (string V_0)

Note that it has a flag (?) 'init'. I am guessing that this flag tells the
runtime to initialize all local variables.

If the IL has a mechanism to guarantee that all local variables have default
values, C# is FORCING us write REDUNDANT code; if not, then VB compiler is
generating VERY WRONG code.

"Neo The One" wrote:
I think C# is forcing us to write more code by enforcing a rule that can be
summarized as 'A local variable must be assgined *explicitly* before reading
its value.'

If you are interested in what I mean, please look at this feedback my me:

http://lab.msdn.microsoft.com/produc...2-d266472a84ac

If you think I am right, please vote for this feedback.

Thanks.

Nov 17 '05 #22

P: n/a

"Neo The One" <Ne*******@discussions.microsoft.com> wrote in message
news:3B**********************************@microsof t.com...
After reading all the replies, I think my problem now turns into another
problem:

Does the COR (Common Object Runtime) provide such a mechanism to ensure
call
lcoal variables have default values?

If the COR guarantees that, then C# compiler is generating redundant code.
Otherwise, VB compiler is generating WRONG code (as many of you have
pointed
out).

Today, I used the ILDasm tool (part of .NET SDK) to examine the IL code
generated both by C# and VB compilers. I found that the Lutz Roeder's
Reflector does not give the 'init' flag. Here is the IL code ILDasm gives
me:

.locals init (string V_0)

I guess the init flag(?) tells the COR to initialize all local variables
in
the parentheses.

I also tried to read the IL reference (C:\Program
Files\Microsoft.NET\SDK\v1.1\Tool Developers Guide\docs\Partition III
CIL.doc), but that it does not have explanation about .locals instruction.
Does anyone know where can I find a complete reference to IL instructions?

Thanks.

Are you sure you did read all other replies, this is exactly what we are
talking about.
Point is, that C# requires explict initialization of locals before using
(which is a good thing!), but at the same time it emits the '.locals init'
directive that forces the JIT to generate initialization code too.

The latest CLI TR can be found here...
http://www.ecma-international.org/pu...s/Ecma-335.htm
<quote>
If init is specified, the variables are initialized to their default values
according to their type:
reference types are initialized to null and value types are zeroed out.
[Note: Verifiable methods shall include the init keyword.....
</quote>

Willy.


Willy.
Nov 17 '05 #23

P: n/a

"Willy Denoyette [MVP]" <wi*************@telenet.be> wrote in message
news:u%****************@TK2MSFTNGP15.phx.gbl...

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Willy Denoyette [MVP] <wi*************@telenet.be> wrote:
> That may be true of the implementation, but not of the specification.
> I
> should have made that clearer - it's actually important when it comes
> to calling methods with "out" parameters written in other languages,
> but within C# the value is effectively unspecified. This is perhaps
> unfortunate...

Mind to tell us what specification are you talking about?


The C# specification (rather than the CLI spec).

From section 12.1.7 (ECMA numbering):

<quote>
A local variable is not automatically initialized and thus has no
default value.
</quote>


Which tends to be incorrect, it's the C# compiler that emits the ".locals
init" , right?.
To me it's clear that C#, J#, C++ and VB.NET compilers emits a '.locals
init' directive and as a result the locals are initialized to zero.
Sure,
the locals are not explicitely initialized (as per specification?), but
all
(MS) compilers do emit the .local init directive in the method header,
question is based on what specification.


See above. I believe a C# compiler which actually initialised all local
ints to 1 instead of 0 would still be compliant with the C# spec, for
example.

Agreed, any value would do, but according "The C# specification" it's not
initialized at all, which is not true.
Not sure what 'out' parameters have to do with this, though, the callee
does/should not consider an out argument being 'initialized' by the
caller,
the value it as doesn't matter anyway.


The callee can't see the value in C#, but can in other languages (and
can in C# using RealProxy) - therefore it must be a valid value. For
instance, if it's a reference, it can't be just some arbitrary value.


Why not?, 'out' passes the address of the variable, sure the address must
be valid, but the 'value' it points to may contain anything.

consider a ref. type string as local variable.

string s; // no explicit init. required.
F(out s);

the local (a reference) is on the stack (suppose 32 bit windows here) and
implicitely initialized to 0 by '.locals init'.

address value
0x0012b644 0x00000000

'out s' argument passed:
= 0x0012b644

The callee expects a 'valid' pointer to a type string (a ref) and managed
code callees cannot take the value pointed by, they can only assign (this
is compiler enforced).

F(out s)
{
string t = s; // invalid code, C# compiler error
s = "newstring"; //Valid - this sets the 'value' of the variable
pointed to by the arg. to the reference of the string instance.
...
now consider this C# snip:

string s = null; // explicit init. compiler enforced
{
...
F(out s);

The passed arg. is exactly the same..

address value
0x0012b644 0x00000000

'out s' argument passed:
= 0x0012b644

but here the generated machine code contains a superflous inititalization
of s (see my other reply).
I'm not sure what other languages you refer to, all managed languages I
know use the same semantics for out arguments. When calling native C using
out arguments, it's the PInvoke layer who takes care about the marshaling,
and it's up to the callee to know the semantics.

Willy.


Tweaking the IL and removing "init" from the ' .locals init ' directive
results in non-verifiable code.

Peverify output:
[IL]: Error: ............. initlocals must be for verifiable methods with
one or more local variables.

So, all locals must be initialized to their default values as per CIL
specifications to produce verifiable methods. And the locals must be
initialized before usage as per C# requirement, which results in double
inititializations which are not optimized away by the JIT. This is the price
we have to pay for being 'explicit' ;-).

Willy.
Nov 17 '05 #24

P: n/a
I have not read the spec yet...

But if what you said is true, then C# compiler is generating REDUNDANT code
or at least it should not emit the init flag. Because init flag initialize
local vars, that takes CPU time. By C# rule, before reading any local var, I
have explicitly assign a value to it; if I assign a non-default value, the
previous initialization is redundant and waste of CPU cycles; if I assign a
default value, the previous initialization is also redundant and a waste of
CPU time. So the conclusion is the code generated by C# compiler is redundant.

I do think that the rule that local vars must be explicitly assigned before
reading their values is wise and it ensures secure and correct code. I never
doubt the design of the language spec. But now the problem is that C#
compiler is generating code that is not optmized, which we C/C++ programmers
always care about and object to.
"Willy Denoyette [MVP]" wrote:
Are you sure you did read all other replies, this is exactly what we are
talking about.
Point is, that C# requires explict initialization of locals before using
(which is a good thing!), but at the same time it emits the '.locals init'
directive that forces the JIT to generate initialization code too.

The latest CLI TR can be found here...
http://www.ecma-international.org/pu...s/Ecma-335.htm
<quote>
If init is specified, the variables are initialized to their default values
according to their type:
reference types are initialized to null and value types are zeroed out.
[Note: Verifiable methods shall include the init keyword.....
</quote>

Willy.


Willy.

Nov 17 '05 #25

P: n/a
Thanks for directing me to the spec. I have not read the spec yet...

But if what you said is true, then C# compiler is generating REDUNDANT code
or at least it should not emit the init flag. Because init flag initialize
local vars, that takes CPU time. By C# rule, before reading any local var, I
have explicitly assign a value to it; if I assign a non-default value, the
previous initialization is redundant and waste of CPU cycles; if I assign a
default value, the previous initialization is also redundant and a waste of
CPU time. So the conclusion is the code generated by C# compiler is redundant.

I do think that the rule that local vars must be explicitly assigned before
reading their values is wise and it ensures secure and correct code. I never
doubt the design of the language spec. But now the problem is that C#
compiler is generating code that is not optmized, which we C/C++ programmers
always care about and object to.
"Willy Denoyette [MVP]" wrote:
Are you sure you did read all other replies, this is exactly what we are
talking about.
Point is, that C# requires explict initialization of locals before using
(which is a good thing!), but at the same time it emits the '.locals init'
directive that forces the JIT to generate initialization code too.

The latest CLI TR can be found here...
http://www.ecma-international.org/pu...s/Ecma-335.htm
<quote>
If init is specified, the variables are initialized to their default values
according to their type:
reference types are initialized to null and value types are zeroed out.
[Note: Verifiable methods shall include the init keyword.....
</quote>

Willy.


Willy.

Nov 17 '05 #26

P: n/a
Althoug talking about VB is off topic, but I'd like to add a comment that
based on the spec, VB compiler is generating CORRECT and GOOD code regarding
local variables.

My points:
1. The VB language spec states that all variables (local or class members)
are initialized.
2. The IL code generated by VB compiler has the init flag that ensures all
local variables are propertly initialized. See page 203 of Ecma-335.pdf
(http://www.ecma-international.org/pu...s/Ecma-335.htm,
thanks to Willy [MVP])

BTW, I am not a fan of VB. I hope this does arise that holy thing I always
try best to avoid. Actually, I am a C# fan... I was only speaking nothing but
facts.

"Neo The One" wrote:
I think C# is forcing us to write more code by enforcing a rule that can be
summarized as 'A local variable must be assgined *explicitly* before reading
its value.'

If you are interested in what I mean, please look at this feedback my me:

http://lab.msdn.microsoft.com/produc...2-d266472a84ac

If you think I am right, please vote for this feedback.

Thanks.

Nov 17 '05 #27

P: n/a

"Neo The One" <Ne*******@discussions.microsoft.com> wrote in message
news:C5**********************************@microsof t.com...
I have not read the spec yet...

But if what you said is true, then C# compiler is generating REDUNDANT
code
or at least it should not emit the init flag. Because init flag initialize
local vars, that takes CPU time.
This flag is required by all languages that generate verifiable code, please
read the CLI specs.

By C# rule, before reading any local var, I have explicitly assign a value to it; if I assign a non-default value, the
previous initialization is redundant and waste of CPU cycles; Again, this is also true for VB.NET and all other languages to generate
verifiable code.

if I assign a default value, the previous initialization is also redundant and a waste
of
CPU time. So the conclusion is the code generated by C# compiler is
redundant.
Same here, see above....
I do think that the rule that local vars must be explicitly assigned
before
reading their values is wise and it ensures secure and correct code. I
never
doubt the design of the language spec. But now the problem is that C#
compiler is generating code that is not optmized, which we C/C++
programmers
always care about and object to.


These 'redundant' init, take two CPU cycles on modern CPU's, you don't care
about these don't you? Do you know how many cycles are needed to push/pop
registers on the stack, even when they aren't used in the called method?
Do you know how many cycles it takes to initialize an exception frame when
your method contains a protected block, like the following?

F()
{
string s = nul;
try {
...
}
....

is this a reason for C/C++ not to use exceptions in C++? I guess not.
Agreed, the JIT could optimize away the redundant init's, but then the JIT
has to burn some extra (redundant?) cycles for it.
Anyway, if you really think this is an issue, I would suggest you stick with
C (he! stay away from C++ too) or start to code in assembly if you realy
want to save the last cycle, but this is not what modern languages should
(too much) care about.

Willy.

Nov 17 '05 #28

P: n/a
Sorry, I raised the problem because I am caring about the 'consistence'
between language spec and implementation. I agree that 2 CPU cycles is
something we can ignore compared to database queries, disk activities,
IO completion, thread context switching, etc. But the amount of CPU
cycles is not what I care. I mentioned this in the sense that the C#
compiler is generating redundant code - no matter how little redundance
it is.

Of course VB compiler generates the same IL code, but it does what VB
language spec tells it to do. Right?

About verifiable methods:
Sorry I have no time to read thru the spec. I think if all methods are
required to include the init directive, then C# is left in an awkward
situation - it forces a rule that has already been done by underlying
rumtime.

I have my own thoughts about C# language design, but I know I am only a
'small potato' and can have hardly any influence on it. But I want C# to
be the *perfect* language I always dream of. I am sending feedbacks to
the Product Feedback Center. I am also tracking this feedback
http://lab.msdn.microsoft.com/produc...7-f4e2676f3c9d
and I think adding a VB like With/End With construct will make coding
easier and more productive.

Thanks for your time.

is this a reason for C/C++ not to use exceptions in C++? I guess not.
Agreed, the JIT could optimize away the redundant init's, but then the JIT
has to burn some extra (redundant?) cycles for it.
Anyway, if you really think this is an issue, I would suggest you stick with
C (he! stay away from C++ too) or start to code in assembly if you realy
want to save the last cycle, but this is not what modern languages should
(too much) care about.

Willy.

Nov 17 '05 #29

P: n/a
"Willy Denoyette [MVP]" wrote:

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Willy Denoyette [MVP] <wi*************@telenet.be> wrote:
> That may be true of the implementation, but not of the specification. I
> should have made that clearer - it's actually important when it comes
> to calling methods with "out" parameters written in other languages,
> but within C# the value is effectively unspecified. This is perhaps
> unfortunate...

Mind to tell us what specification are you talking about?
The C# specification (rather than the CLI spec).

From section 12.1.7 (ECMA numbering):

<quote>
A local variable is not automatically initialized and thus has no
default value.
</quote>


Which tends to be incorrect, it's the C# compiler that emits the ".locals
init" , right?.


no, the spec is correct. the purpose of the spec is not to describe what
the microsoft C# compiler does exactly. it's a outline of the minimum set of
rules that all C# compilers should follow.
To me it's clear that C#, J#, C++ and VB.NET compilers emits a '.locals
init' directive and as a result the locals are initialized to zero. Sure,
the locals are not explicitely initialized (as per specification?), but
all
(MS) compilers do emit the .local init directive in the method header,
question is based on what specification.


See above. I believe a C# compiler which actually initialised all local
ints to 1 instead of 0 would still be compliant with the C# spec, for
example.

Agreed, any value would do, but according "The C# specification" it's not
initialized at all, which is not true.


Jon's point is that according to the C# spec, a C# compiler is not required
to initialize the local variables. whether some do is completely irrelevant
because it's not a behavior that the spec demands. and hence, you can't rely
on it. and clearly, MS C# compiler still forces you to initialize.

Nov 17 '05 #30

P: n/a

"Edward Yang" <ne***********@msn.com> wrote in message
news:Oq**************@TK2MSFTNGP09.phx.gbl...
Sorry, I raised the problem because I am caring about the 'consistence'
between language spec and implementation. I agree that 2 CPU cycles is
something we can ignore compared to database queries, disk activities, IO
completion, thread context switching, etc. But the amount of CPU cycles is
not what I care. I mentioned this in the sense that the C# compiler is
generating redundant code - no matter how little redundance it is.
Well, I'm with you on this, the C# language specs. could mention this
implicit 'default' initialization as per CLI requirements (ECMA latest
Partition II 15.4.1.3), but I would not say that the C# compiler is
generating redundant code - it's a requirement imposed by the CLI to all
languages. The redundancy comes from the explicit assignment/initialization
requirement imposed by C# language compiler, something that could be relaxed
to a warning when omitted, but this is another discussion.

Of course VB compiler generates the same IL code, but it does what VB
language spec tells it to do. Right?

Which VB.NET language spec's? VB is not an ECMA standard like C#, the VB
language team can change this whenever they feel the need to do so. Like I
said before, the next version of VB flags a non explicitely initialized
local with a compiler warning, so now VB is in the same boat as C# , but it
offers the posibility to 'mask' the warning using the /nowarn:<number_list>
compiler option.
About verifiable methods:
Sorry I have no time to read thru the spec. I think if all methods are
required to include the init directive, then C# is left in an awkward
situation - it forces a rule that has already been done by underlying
rumtime.

I have my own thoughts about C# language design, but I know I am only a
'small potato' and can have hardly any influence on it. But I want C# to
be the *perfect* language I always dream of. I am sending feedbacks to the
Product Feedback Center. I am also tracking this feedback
http://lab.msdn.microsoft.com/produc...7-f4e2676f3c9d
and I think adding a VB like With/End With construct will make coding
easier and more productive.

Thanks for your time.

Willy.
Nov 17 '05 #31

P: n/a
The point is that it's imposed by the ECMA CLI specs (see .locals in
Partition II) ), to produce verifiable methods the compiler must emit
..locals init in order to initialize the locals. You can try this by removing
the init from the .locals directive from the il generated by the C#
compiler, if you run Peverify on the assembly following error message will
be generated.
[IL]: Error: [.blabla ...........][offset 0x0000000A] initlocals must be set
for verifiable methods with one or more local variables.

Now, if I understand you correctly, the ECMA C# language specs. don't
require the C# compilers to generate verifiable methods.
But MS compiler produces only verifiable code and the MSDN "C# Language
specification" explicitely states that locals are NOT initialized, which
can't hold when producing verifiable code and that's my point.
<quote MSDN "C# Language specification"
A local variable is not automatically initialized and thus has no default
value.
/quote>

Willy.

"Daniel Jin" <Da*******@discussions.microsoft.com> wrote in message
news:C8**********************************@microsof t.com...
"Willy Denoyette [MVP]" wrote:

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
> Willy Denoyette [MVP] <wi*************@telenet.be> wrote:
>> > That may be true of the implementation, but not of the
>> > specification. I
>> > should have made that clearer - it's actually important when it
>> > comes
>> > to calling methods with "out" parameters written in other languages,
>> > but within C# the value is effectively unspecified. This is perhaps
>> > unfortunate...
>>
>> Mind to tell us what specification are you talking about?
>
> The C# specification (rather than the CLI spec).
>
> From section 12.1.7 (ECMA numbering):
>
> <quote>
> A local variable is not automatically initialized and thus has no
> default value.
> </quote>
>


Which tends to be incorrect, it's the C# compiler that emits the ".locals
init" , right?.


no, the spec is correct. the purpose of the spec is not to describe what
the microsoft C# compiler does exactly. it's a outline of the minimum set
of
rules that all C# compilers should follow.
>> To me it's clear that C#, J#, C++ and VB.NET compilers emits a
>> '.locals
>> init' directive and as a result the locals are initialized to zero.
>> Sure,
>> the locals are not explicitely initialized (as per specification?),
>> but
>> all
>> (MS) compilers do emit the .local init directive in the method header,
>> question is based on what specification.
>
> See above. I believe a C# compiler which actually initialised all local
> ints to 1 instead of 0 would still be compliant with the C# spec, for
> example.
>

Agreed, any value would do, but according "The C# specification" it's not
initialized at all, which is not true.


Jon's point is that according to the C# spec, a C# compiler is not
required
to initialize the local variables. whether some do is completely
irrelevant
because it's not a behavior that the spec demands. and hence, you can't
rely
on it. and clearly, MS C# compiler still forces you to initialize.

Nov 17 '05 #32

P: n/a
"Willy Denoyette [MVP]" wrote:
The point is that it's imposed by the ECMA CLI specs (see .locals in
Partition II) ), to produce verifiable methods the compiler must emit
..locals init in order to initialize the locals. You can try this by removing
the init from the .locals directive from the il generated by the C#
compiler, if you run Peverify on the assembly following error message will
be generated.
[IL]: Error: [.blabla ...........][offset 0x0000000A] initlocals must be set
for verifiable methods with one or more local variables.

Now, if I understand you correctly, the ECMA C# language specs. don't
require the C# compilers to generate verifiable methods.
But MS compiler produces only verifiable code and the MSDN "C# Language
specification" explicitely states that locals are NOT initialized, which
can't hold when producing verifiable code and that's my point.
<quote MSDN "C# Language specification"
A local variable is not automatically initialized and thus has no default
value.
/quote>

if I'm not mistaken, the spec on MSDN is the ECMA spec.

and regarding verifiable method, here's what CLI spec says about
verifiability. (Partition III, 1.8)

<quote>
It is perfectly acceptable to generate CIL code that is not verifiable, but
which is known to be memory safe by the compiler writer. Thus, conforming CIL
may not be verifiable, even though the producing compiler may know that it is
memory safe.
</quote>

so I can write a C# compiler, which doesn't output verifiable methods, yet
if I follow C# spec, it's still known to be memory safe. verifiability is
not a requirement, so it seems.
Willy.

"Daniel Jin" <Da*******@discussions.microsoft.com> wrote in message
news:C8**********************************@microsof t.com...
"Willy Denoyette [MVP]" wrote:

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
> Willy Denoyette [MVP] <wi*************@telenet.be> wrote:
>> > That may be true of the implementation, but not of the
>> > specification. I
>> > should have made that clearer - it's actually important when it
>> > comes
>> > to calling methods with "out" parameters written in other languages,
>> > but within C# the value is effectively unspecified. This is perhaps
>> > unfortunate...
>>
>> Mind to tell us what specification are you talking about?
>
> The C# specification (rather than the CLI spec).
>
> From section 12.1.7 (ECMA numbering):
>
> <quote>
> A local variable is not automatically initialized and thus has no
> default value.
> </quote>
>

Which tends to be incorrect, it's the C# compiler that emits the ".locals
init" , right?.


no, the spec is correct. the purpose of the spec is not to describe what
the microsoft C# compiler does exactly. it's a outline of the minimum set
of
rules that all C# compilers should follow.

>> To me it's clear that C#, J#, C++ and VB.NET compilers emits a
>> '.locals
>> init' directive and as a result the locals are initialized to zero.
>> Sure,
>> the locals are not explicitely initialized (as per specification?),
>> but
>> all
>> (MS) compilers do emit the .local init directive in the method header,
>> question is based on what specification.
>
> See above. I believe a C# compiler which actually initialised all local
> ints to 1 instead of 0 would still be compliant with the C# spec, for
> example.
>
Agreed, any value would do, but according "The C# specification" it's not
initialized at all, which is not true.


Jon's point is that according to the C# spec, a C# compiler is not
required
to initialize the local variables. whether some do is completely
irrelevant
because it's not a behavior that the spec demands. and hence, you can't
rely
on it. and clearly, MS C# compiler still forces you to initialize.


Nov 17 '05 #33

P: n/a

"Daniel Jin" <Da*******@discussions.microsoft.com> wrote in message
news:A8**********************************@microsof t.com...
"Willy Denoyette [MVP]" wrote:
The point is that it's imposed by the ECMA CLI specs (see .locals in
Partition II) ), to produce verifiable methods the compiler must emit
..locals init in order to initialize the locals. You can try this by
removing
the init from the .locals directive from the il generated by the C#
compiler, if you run Peverify on the assembly following error message
will
be generated.
[IL]: Error: [.blabla ...........][offset 0x0000000A] initlocals must be
set
for verifiable methods with one or more local variables.

Now, if I understand you correctly, the ECMA C# language specs. don't
require the C# compilers to generate verifiable methods.
But MS compiler produces only verifiable code and the MSDN "C# Language
specification" explicitely states that locals are NOT initialized, which
can't hold when producing verifiable code and that's my point.
<quote MSDN "C# Language specification"
A local variable is not automatically initialized and thus has no default
value.
/quote>

if I'm not mistaken, the spec on MSDN is the ECMA spec.

If you mean it's exactly the same document, then the answer is no. The ECMA
document is based on a submission from different parties (Microsoft, hp...),
there are a lot of differences, but I'm not sure whether they differ in
'real' specifications. Anyway both documents do state that <locals ARE NOT
initialized ...>, and that sounds definitive, right?
and regarding verifiable method, here's what CLI spec says about
verifiability. (Partition III, 1.8)

<quote>
It is perfectly acceptable to generate CIL code that is not verifiable,
but
which is known to be memory safe by the compiler writer. Thus, conforming
CIL
may not be verifiable, even though the producing compiler may know that it
is
memory safe.
</quote>

Sure, ilasm can produce non-verifiable code, but it will only pass the
security check on the CLR when loaded from local storage.
so I can write a C# compiler, which doesn't output verifiable methods, yet
if I follow C# spec, it's still known to be memory safe. verifiability is
not a requirement, so it seems.


No it's not explicitely required by the C# specification, but Microsoft's C#
compiler (like the other Microsoft language compilers) do produce verifiable
methods, it does emit the .locals init directive and as such it initializes
local variable, what's more MS C# compiler cannot produce non-verifiable
code.
Non verifiable code can only run in full trust scenarios, that means that
compilers that generate non verifiable assemblies will fail verification on
the CLR when loaded from the network, and will be able to run only from the
local disk. Note that the keyword 'init' does not emit any IL, it's a JIT
directive , and it's the JIT that will throw an exception when init is
omitted in a partial trust scenario.
Also, some of the FCL assemblies do have the requirement to run in partial
trust scenarios, so I guess this is reason enough to make it the default.
Willy.
Nov 17 '05 #34

P: n/a
Willy Denoyette [MVP] <wi*************@telenet.be> wrote:
The C# specification (rather than the CLI spec).

From section 12.1.7 (ECMA numbering):

<quote>
A local variable is not automatically initialized and thus has no
default value.
</quote>
Which tends to be incorrect, it's the C# compiler that emits the ".locals
init" , right?.


I believe it's just doing something it's not required to by the C# spec
- but it may be required to by the CIL spec. Put it this way - from
within pure C#, without using RealProxy or anything like that, I don't
believe you can show it to be violating the spec.
See above. I believe a C# compiler which actually initialised all local
ints to 1 instead of 0 would still be compliant with the C# spec, for
example.


Agreed, any value would do, but according "The C# specification" it's not
initialized at all, which is not true.


I think it's arguable.
Not sure what 'out' parameters have to do with this, though, the callee
does/should not consider an out argument being 'initialized' by the
caller,
the value it as doesn't matter anyway.


The callee can't see the value in C#, but can in other languages (and
can in C# using RealProxy) - therefore it must be a valid value. For
instance, if it's a reference, it can't be just some arbitrary value.


Why not?, 'out' passes the address of the variable, sure the address must be
valid, but the 'value' it points to may contain anything.


No, it has to point to an actual reference.
consider a ref. type string as local variable.

string s; // no explicit init. required.
F(out s);

the local (a reference) is on the stack (suppose 32 bit windows here) and
implicitely initialized to 0 by '.locals init'.

address value
0x0012b644 0x00000000

'out s' argument passed:
= 0x0012b644

The callee expects a 'valid' pointer to a type string (a ref) and managed
code callees cannot take the value pointed by, they can only assign (this is
compiler enforced).
But that's the point - it's only compiler enforced in C#, and you might
be calling into non-C# code. Even using C#, if you use RealProxy to
implement an interface, you can get that initial value as an object
reference. Imagine if it were a reference to some sensitive piece of
memory elsewhere - very bad news from a security point of view.
but here the generated machine code contains a superflous inititalization of
s (see my other reply).
I'm not sure what other languages you refer to, all managed languages I know
use the same semantics for out arguments. When calling native C using out
arguments, it's the PInvoke layer who takes care about the marshaling, and
it's up to the callee to know the semantics.


It may be up to the callee to know the semantics, but unless the CLI
spec (which I haven't checked) says that those semantics are actually
enforced, you could still have managed code with a nasty security
problem if the "uninitialised" value could be examined.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 17 '05 #35

P: n/a

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP*********************@msnews.microsoft.com. ..
Willy Denoyette [MVP] <wi*************@telenet.be> wrote:
Agreed, any value would do, but according "The C# specification" it's not
initialized at all, which is not true.


I think it's arguable.

See below.
Why not?, 'out' passes the address of the variable, sure the address must
be
valid, but the 'value' it points to may contain anything.


No, it has to point to an actual reference.


No its not, passing a pointer to a 'null' reference is valid, how would you
explain following is valid, or do you call null an actual reference?.

{
string s;
// or this...
// string s = null;
F(out s);
Console.WriteLine(s);

}
static void F(out string s)
{
s = "test";
}
consider a ref. type string as local variable.

string s; // no explicit init. required.
F(out s);

the local (a reference) is on the stack (suppose 32 bit windows here) and
implicitely initialized to 0 by '.locals init'.

address value
0x0012b644 0x00000000

'out s' argument passed:
= 0x0012b644

The callee expects a 'valid' pointer to a type string (a ref) and managed
code callees cannot take the value pointed by, they can only assign (this
is
compiler enforced).
But that's the point - it's only compiler enforced in C#, and you might
be calling into non-C# code. Even using C#, if you use RealProxy to
implement an interface, you can get that initial value as an object
reference. Imagine if it were a reference to some sensitive piece of
memory elsewhere - very bad news from a security point of view.


But who is talking about a pointer to memory elsewhere, we are talking about
locals here and locals are stack allocated, the variable declaration
reserves the location on the stack to hold the variable (whatever its type)
while the out keyword tells the compiler to take the address of the value as
argument, it MUST point to a valid memory location (this is the JIT's task),
but the 'value' it points to doesn't matter, is not verified and so it can
be bit combination.
That means that in this snip:

string s;
string ss = "Just a string";
// this..
string s = null;
// and these
// string s = "Whatever";
// string s = ss;
F(out s);
...
static void F(out string s)
{
s = ...
}

are all valid, all that's required is that the callee assigns the 'value'
pointed to by the argument (a pointer) before leaving the method scope
(again this is compiler enforced).

So, this is not valid...
static void F(out string s)
{ // do whatever, but don't assign to s... }

but here the generated machine code contains a superflous inititalization
of
s (see my other reply).
I'm not sure what other languages you refer to, all managed languages I
know
use the same semantics for out arguments. When calling native C using out
arguments, it's the PInvoke layer who takes care about the marshaling,
and
it's up to the callee to know the semantics.
It may be up to the callee to know the semantics, but unless the CLI
spec (which I haven't checked) says that those semantics are actually
enforced, you could still have managed code with a nasty security
problem if the "uninitialised" value could be examined.


Hmmm, I didn't say the CLI imposes something here, I was talking about
PInvoke and as the callee is unmanaged code we aren't going to discuss
security and other things that might go wrong, if you call into unmanaged
code, all gates are open. What I meant was when passing an argument as
'out', it's up to the interop layer to correctly marshal the pointer or the
data it points to, depending on the argument type and it's attributes. If
there is something wrong with one of these, bad things can happen and the
CLI has nothing to with this.

Sorry, I'm completely lost here I'm starting to think we are talking about
different things here, the OP and I are saying that locals are initialized
to zero, the while the C# specs. explicitely state that "locals are NOT
initialized and they don't contain default values", note that the specs
don't say "you should not assume that locals are compiler initialized'.
I don't have a problem with this explicit initialization in the current
implementation[1], but the OP's point is the redundant initialization
imposed by the C# compiler (also not an issue for me) , while it's not
required by VB.NET nor by C++/CLI.

// this is redundant in the current implementation, but it's C# compiler
enforced, which is not true for the other compilers.
int aLocal = 0;

[1] all MSFT compilers emit .locals init and as such sets the locals to 0
(not explicitly required as per C# specs).
Willy.

Nov 17 '05 #36

P: n/a
Willy Denoyette [MVP] <wi*************@telenet.be> wrote:
Why not?, 'out' passes the address of the variable, sure the address must
be
valid, but the 'value' it points to may contain anything.
No, it has to point to an actual reference.


No its not, passing a pointer to a 'null' reference is valid, how would you
explain following is valid, or do you call null an actual reference?.


Yes, I call null a valid reference. It's a reference to nothing, rather
than a reference to something which is of the wrong type (or possibly
complete garbage) - which is what you could get if the variable were
initialised to some random value.
But that's the point - it's only compiler enforced in C#, and you might
be calling into non-C# code. Even using C#, if you use RealProxy to
implement an interface, you can get that initial value as an object
reference. Imagine if it were a reference to some sensitive piece of
memory elsewhere - very bad news from a security point of view.


But who is talking about a pointer to memory elsewhere, we are talking about
locals here and locals are stack allocated, the variable declaration
reserves the location on the stack to hold the variable (whatever its type)
while the out keyword tells the compiler to take the address of the value as
argument, it MUST point to a valid memory location (this is the JIT's task),
but the 'value' it points to doesn't matter, is not verified and so it can
be bit combination.


No, the value it points to *does* matter when you consider languages
which may not use the same "out" semantics, or RealProxy which exposes
the current value of a variable even when it's passed as an out
parameter. (I have some experience of this as it's caused some pain
when writing EasyMock.NET.)
Here's some sample code which shows the value of a variable which is
passed as an out parameter:

using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Proxies;

public interface IFoo
{
void Whatever (out int i);
}

public class Proxy : RealProxy
{
public Proxy() : base (typeof(IFoo))
{
}

public override IMessage Invoke (IMessage msg)
{
IMethodCallMessage methodCall = (IMethodCallMessage) msg;

object[] args = methodCall.Args;
Console.WriteLine (methodCall.MethodBase.Name);
Console.WriteLine ("Args:");
foreach (object o in args)
{
Console.WriteLine (o);
}
Console.WriteLine ("---");
ReturnMessage retMsg = new ReturnMessage (null,
null,
0,
null,
methodCall);
return retMsg;
}
}

public class Test
{
static void Main()
{
Proxy proxy = new Proxy();
IFoo foo = (IFoo) proxy.GetTransparentProxy();

int x;
foo.Whatever(out x);
x = 10;
foo.Whatever(out x);
}
}
It may be up to the callee to know the semantics, but unless the CLI
spec (which I haven't checked) says that those semantics are actually
enforced, you could still have managed code with a nasty security
problem if the "uninitialised" value could be examined.


Hmmm, I didn't say the CLI imposes something here, I was talking about
PInvoke and as the callee is unmanaged code we aren't going to discuss
security and other things that might go wrong, if you call into unmanaged
code, all gates are open. What I meant was when passing an argument as
'out', it's up to the interop layer to correctly marshal the pointer or the
data it points to, depending on the argument type and it's attributes. If
there is something wrong with one of these, bad things can happen and the
CLI has nothing to with this.


Well, see the above - entirely managed code as far as I'm concerned
(how remoting is actually implemented is another matter of course) and
yet I can see the values of out parameters. If the above out parameter
were a reference type, I would jolly well want that to be a valid value
for the appropriate type, and also *not* a reference to a random object
kicking around the managed heap.
Sorry, I'm completely lost here I'm starting to think we are talking about
different things here, the OP and I are saying that locals are initialized
to zero, the while the C# specs. explicitely state that "locals are NOT
initialized and they don't contain default values", note that the specs
don't say "you should not assume that locals are compiler initialized'.
No, the language *forces* you not to assume that locals are compiler
initialised *apart* from when you end up with nasty tricks liek the
above.
I don't have a problem with this explicit initialization in the current
implementation[1], but the OP's point is the redundant initialization
imposed by the C# compiler (also not an issue for me) , while it's not
required by VB.NET nor by C++/CLI.


Sure. I'm just making the point that it *is* rather important that
there's some initialization somewhere, otherwise there's a potential
security hazard.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 17 '05 #37

P: n/a
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Willy Denoyette [MVP] <wi*************@telenet.be> wrote:
>> Why not?, 'out' passes the address of the variable, sure the address
>> must
>> be
>> valid, but the 'value' it points to may contain anything.
>
> No, it has to point to an actual reference.
No its not, passing a pointer to a 'null' reference is valid, how would
you
explain following is valid, or do you call null an actual reference?.


Yes, I call null a valid reference. It's a reference to nothing, rather
than a reference to something which is of the wrong type (or possibly
complete garbage) - which is what you could get if the variable were
initialised to some random value.
> But that's the point - it's only compiler enforced in C#, and you might
> be calling into non-C# code. Even using C#, if you use RealProxy to
> implement an interface, you can get that initial value as an object
> reference. Imagine if it were a reference to some sensitive piece of
> memory elsewhere - very bad news from a security point of view.


But who is talking about a pointer to memory elsewhere, we are talking
about
locals here and locals are stack allocated, the variable declaration
reserves the location on the stack to hold the variable (whatever its
type)
while the out keyword tells the compiler to take the address of the value
as
argument, it MUST point to a valid memory location (this is the JIT's
task),
but the 'value' it points to doesn't matter, is not verified and so it
can
be bit combination.


No, the value it points to *does* matter when you consider languages
which may not use the same "out" semantics, or RealProxy which exposes
the current value of a variable even when it's passed as an out
parameter. (I have some experience of this as it's caused some pain
when writing EasyMock.NET.)
Here's some sample code which shows the value of a variable which is
passed as an out parameter:

using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Proxies;

public interface IFoo
{
void Whatever (out int i);
}

public class Proxy : RealProxy
{
public Proxy() : base (typeof(IFoo))
{
}

public override IMessage Invoke (IMessage msg)
{
IMethodCallMessage methodCall = (IMethodCallMessage) msg;

object[] args = methodCall.Args;
Console.WriteLine (methodCall.MethodBase.Name);
Console.WriteLine ("Args:");
foreach (object o in args)
{
Console.WriteLine (o);
}
Console.WriteLine ("---");
ReturnMessage retMsg = new ReturnMessage (null,
null,
0,
null,
methodCall);
return retMsg;
}
}

public class Test
{
static void Main()
{
Proxy proxy = new Proxy();
IFoo foo = (IFoo) proxy.GetTransparentProxy();

int x;
foo.Whatever(out x);
x = 10;
foo.Whatever(out x);
}
}
> It may be up to the callee to know the semantics, but unless the CLI
> spec (which I haven't checked) says that those semantics are actually
> enforced, you could still have managed code with a nasty security
> problem if the "uninitialised" value could be examined.


Hmmm, I didn't say the CLI imposes something here, I was talking about
PInvoke and as the callee is unmanaged code we aren't going to discuss
security and other things that might go wrong, if you call into unmanaged
code, all gates are open. What I meant was when passing an argument as
'out', it's up to the interop layer to correctly marshal the pointer or
the
data it points to, depending on the argument type and it's attributes. If
there is something wrong with one of these, bad things can happen and the
CLI has nothing to with this.


Well, see the above - entirely managed code as far as I'm concerned
(how remoting is actually implemented is another matter of course) and
yet I can see the values of out parameters. If the above out parameter
were a reference type, I would jolly well want that to be a valid value
for the appropriate type, and also *not* a reference to a random object
kicking around the managed heap.
Sorry, I'm completely lost here I'm starting to think we are talking
about
different things here, the OP and I are saying that locals are
initialized
to zero, the while the C# specs. explicitely state that "locals are NOT
initialized and they don't contain default values", note that the specs
don't say "you should not assume that locals are compiler initialized'.


No, the language *forces* you not to assume that locals are compiler
initialised *apart* from when you end up with nasty tricks liek the
above.
I don't have a problem with this explicit initialization in the current
implementation[1], but the OP's point is the redundant initialization
imposed by the C# compiler (also not an issue for me) , while it's not
required by VB.NET nor by C++/CLI.


Sure. I'm just making the point that it *is* rather important that
there's some initialization somewhere, otherwise there's a potential
security hazard.


Jon,
Sure. I'm just making the point that it *is* rather important that
there's some initialization somewhere, otherwise there's a potential
security hazard.


This thread is being forked a couple of times which may have resulted in
some mis-understandings, but finally it looks like we are in full
agreement...
Our argumentation started when you said the "Local variables aren't assigned
to anything by default,..", to which I replied "Actually they are, the IL
directive .locals init, emitted by C#...". After which you replied that this
was an implementation issue not enforced by the C# specs. I replied (ok here
I was sidetracked, I replied to Daniel), that it was required by the CLI,
that says that methods must have .locals init in their headers (actually the
localsinit flag) to be verifiable, and that all MSFT compilers did emit this
directive in order to produce verifiable code.
Then came the discussion about 'out' arguments, where I said that the value
of the variable could contain anything, it wont stop you from calling any
method that expected a pointer to a type, and you replied "he!, bad things
can happen when the variable doesn't contain 'valid data' ... and it's a
security hazard...".
Agreed, this is what verifiability is all about, if a compiler doesn't emit
the .locals init, resulting in non-verifiable code, and the callee is a
remoting proxy or doesn't follow the out semantics (which can't be enforced
by the CLI), bad things can happen. But, and this was my point, the (MS) C#
compiler doesn't allow you to produce non-verifiable code, that's why it
sets the localsinit flag in the method headers, which forces a conformant
CLI (the JIT in the CLR) to initialize the locals and the memory pool to 0.
Note also that I did not say that the C# compiler emits IL to initialize the
local variables, this would result in non verifiable code anyway,
verifiability means that the locals are initialized before the method is
entered (at IL level) and this is only possible by setting the localsinit
flag and let the CLI handle the details of the initialization of both locals
and the memory pool (if any).

Willy.

Nov 17 '05 #38

P: n/a
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Willy Denoyette [MVP] <wi*************@telenet.be> wrote:
>> Why not?, 'out' passes the address of the variable, sure the address
>> must
>> be
>> valid, but the 'value' it points to may contain anything.
>
> No, it has to point to an actual reference.
No its not, passing a pointer to a 'null' reference is valid, how would
you
explain following is valid, or do you call null an actual reference?.


Yes, I call null a valid reference. It's a reference to nothing, rather
than a reference to something which is of the wrong type (or possibly
complete garbage) - which is what you could get if the variable were
initialised to some random value.
> But that's the point - it's only compiler enforced in C#, and you might
> be calling into non-C# code. Even using C#, if you use RealProxy to
> implement an interface, you can get that initial value as an object
> reference. Imagine if it were a reference to some sensitive piece of
> memory elsewhere - very bad news from a security point of view.


But who is talking about a pointer to memory elsewhere, we are talking
about
locals here and locals are stack allocated, the variable declaration
reserves the location on the stack to hold the variable (whatever its
type)
while the out keyword tells the compiler to take the address of the value
as
argument, it MUST point to a valid memory location (this is the JIT's
task),
but the 'value' it points to doesn't matter, is not verified and so it
can
be bit combination.


No, the value it points to *does* matter when you consider languages
which may not use the same "out" semantics, or RealProxy which exposes
the current value of a variable even when it's passed as an out
parameter. (I have some experience of this as it's caused some pain
when writing EasyMock.NET.)
Here's some sample code which shows the value of a variable which is
passed as an out parameter:

using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Proxies;

public interface IFoo
{
void Whatever (out int i);
}

public class Proxy : RealProxy
{
public Proxy() : base (typeof(IFoo))
{
}

public override IMessage Invoke (IMessage msg)
{
IMethodCallMessage methodCall = (IMethodCallMessage) msg;

object[] args = methodCall.Args;
Console.WriteLine (methodCall.MethodBase.Name);
Console.WriteLine ("Args:");
foreach (object o in args)
{
Console.WriteLine (o);
}
Console.WriteLine ("---");
ReturnMessage retMsg = new ReturnMessage (null,
null,
0,
null,
methodCall);
return retMsg;
}
}

public class Test
{
static void Main()
{
Proxy proxy = new Proxy();
IFoo foo = (IFoo) proxy.GetTransparentProxy();

int x;
foo.Whatever(out x);
x = 10;
foo.Whatever(out x);
}
}
> It may be up to the callee to know the semantics, but unless the CLI
> spec (which I haven't checked) says that those semantics are actually
> enforced, you could still have managed code with a nasty security
> problem if the "uninitialised" value could be examined.


Hmmm, I didn't say the CLI imposes something here, I was talking about
PInvoke and as the callee is unmanaged code we aren't going to discuss
security and other things that might go wrong, if you call into unmanaged
code, all gates are open. What I meant was when passing an argument as
'out', it's up to the interop layer to correctly marshal the pointer or
the
data it points to, depending on the argument type and it's attributes. If
there is something wrong with one of these, bad things can happen and the
CLI has nothing to with this.


Well, see the above - entirely managed code as far as I'm concerned
(how remoting is actually implemented is another matter of course) and
yet I can see the values of out parameters. If the above out parameter
were a reference type, I would jolly well want that to be a valid value
for the appropriate type, and also *not* a reference to a random object
kicking around the managed heap.
Sorry, I'm completely lost here I'm starting to think we are talking
about
different things here, the OP and I are saying that locals are
initialized
to zero, the while the C# specs. explicitely state that "locals are NOT
initialized and they don't contain default values", note that the specs
don't say "you should not assume that locals are compiler initialized'.


No, the language *forces* you not to assume that locals are compiler
initialised *apart* from when you end up with nasty tricks liek the
above.
I don't have a problem with this explicit initialization in the current
implementation[1], but the OP's point is the redundant initialization
imposed by the C# compiler (also not an issue for me) , while it's not
required by VB.NET nor by C++/CLI.


Sure. I'm just making the point that it *is* rather important that
there's some initialization somewhere, otherwise there's a potential
security hazard.


Jon,
Sure. I'm just making the point that it *is* rather important that
there's some initialization somewhere, otherwise there's a potential
security hazard.


This thread is being forked a couple of times which may have resulted in
some mis-understandings, but finally it looks like we are in full
agreement...
Our argumentation started when you said the "Local variables aren't assigned
to anything by default,..", to which I replied "Actually they are, the IL
directive .locals init, emitted by C#...". After which you replied that this
was an implementation issue not enforced by the C# specs. I replied (ok here
I was sidetracked, I replied to Daniel), that it was required by the CLI,
that says that methods must have .locals init in their headers (actually the
localsinit flag) to be verifiable, and that all MSFT compilers did emit this
directive in order to produce verifiable code.
Then came the discussion about 'out' arguments, where I said that the value
of the variable could contain anything, it wont stop you from calling any
method that expected a pointer to a type, and you replied "he!, bad things
can happen when the variable doesn't contain 'valid data' ... and it's a
security hazard...".
Agreed, this is what verifiability is all about, if a compiler doesn't emit
the .locals init, resulting in non-verifiable code, and the callee is a
remoting proxy or doesn't follow the out semantics (which can't be enforced
by the CLI), bad things can happen. But, and this was my point, the (MS) C#
compiler doesn't allow you to produce non-verifiable code, that's why it
sets the localsinit flag in the method headers, which forces a conformant
CLI (the JIT in the CLR) to initialize the locals and the memory pool to 0.
Note also that I did not say that the C# compiler emits IL to initialize the
local variables, this would result in non verifiable code anyway,
verifiability means that the locals are initialized before the method is
entered (at IL level) and this is only possible by setting the localsinit
flag and let the CLI handle the details of the initialization of both locals
and the memory pool (if any).

Willy.

Nov 17 '05 #39

P: n/a
Willy Denoyette [MVP] <wi*************@telenet.be> wrote:
Sure. I'm just making the point that it *is* rather important that
there's some initialization somewhere, otherwise there's a potential
security hazard.


This thread is being forked a couple of times which may have resulted in
some mis-understandings, but finally it looks like we are in full
agreement...


Goodo :)

<snip - I agree with everything written>

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 17 '05 #40

P: n/a
Willy Denoyette [MVP] <wi*************@telenet.be> wrote:
Sure. I'm just making the point that it *is* rather important that
there's some initialization somewhere, otherwise there's a potential
security hazard.


This thread is being forked a couple of times which may have resulted in
some mis-understandings, but finally it looks like we are in full
agreement...


Goodo :)

<snip - I agree with everything written>

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 17 '05 #41

This discussion thread is closed

Replies have been disabled for this discussion.