remove struct's default constructor?

Z

Zytan

The point is that no constructor call is made in certain circumstances.
That's actually stated as the reason for not allowing default constructors
on value types (on some developer's blog) -- they weren't willing to
guarantee they would always be called.

So, basically, it is regarded as a default constructor. It's just
that all it does it zero things out, so it most cases, it needn't be
called, so it isn't called. Because of this, it cannot be replaced.
That's why C# doesn't allow a parameterless struct constructor. If
none of the above were true, there would be no issue with C# allowing
the coding of a parameterless default constructor. I think this
proves pretty conclusively that struct's have default constructors.

I can see why people, being pendantic (which is often needed in
programming concepts, it's not a bad thing) think there is no default
cosntructor, because none is specifically called in the byte code that
results. But, we really are talking about the C# language here, not
the resulting byte code. Just because something it optimized out, it
doesn't mean it's not there (conceptually, in terms of the language
itself). We've just been speaking two languages. None the less, I
think MSDN is 100% correct in its position that structs have default
constructors, and if they didn't, we'd be able to make our own
parameterless constructors, which we can't.

Zytan
 
Z

Zytan

No, it doesn't provide any evidence, there is no such thing like a "default constructor"
(called a "user defined special member function" in C++) for value types emitted by the
managed compilers, nor can you define one yourself, except when using IL where you can do
almost everything even produce very unsafe code.
Write some code and look at the IL (and even better at the JITted code), there is no .ctor()
in a value type nor is there a "call" to such constructor ever emitted, all there is, is a
initobj instruction, but even this one is optimized away by the JIT compiler.

Just because IL doesn't have it, it doesn't mean that's what C# allows
or not. You've just said IL can be used to make unsafe code
(presumably that C# would not allow). I think we're speaking two
languages here. Just because something is optimized out (when making
the IL), it doesn't mean it doesn't exist (in C#).
True, there is no "default constructor" for value types.
and therefore doesn't have

It's a reason why it can be optimized out.
True, that's why there is no such "default constructor", why do you keep on insisting on
this?

Optimization of code doesn't mean the optimized out portion doesn't
exist.

I am insisting on this, since no one has shown any evidence that MSDN
is wrong.
A parameter-less user defined constructor *is* a default constructor!

Ok. Elsewhere, it was mentioned that it could not be guaranteed that
default constructors could be called. Implying, from what I could
see, that it was ok to not call a default constructor that just zeroes
things, since they are already zeroed. But, if you made your own, and
C# could not guarantee that it'd be called, then you end up with
something you didn't expect.
And value types DO NOT
SUPPORT default constructors!

Is this your opinion? Or is this something that is stated? It seems
to fly in the face of other opinions. So, it's hard to say which is
actually fact.
Even if you are directly using IL as implementation language, and you define a default
constructor on a value class, still, the home of the value type will be initialized to zero,
before you explicitly call the constructor. This because the initialization is NOT part of
the construction, its simply part of the initialization of the local variables at method
entry time.

Yes, I know.
No managed language compiler I know of,will generate a default constructor. Check [1] [2]
and [3] so see what ECMA says about this.
Especially [3] is what you should read, it explains how value classes can be *initialized*.

Do this apply to C#? Some of them mention C++/CLI.

I now see two views, and both appropriately explain what is seen,
except that they both don't agree on symantics.

Zytan
 
Z

Zytan

Again, I will ask: Why does C# disallow a parameterless constructor?
Ah, no - there I disagree. I would say that a default constructor is
one supplied by the compiler. It is a public, parameterless constructor
which looks identical to one which can (for reference types, obviously)
be supplied in code, but it's often handy to be able to distinguish
between a default constructor as generated by the compiler and a public
parameterless constructor as supplied by the user.

Ok, thanks, I was having trouble with that statement, as well, but I
couldn't pin it down.
I haven't seen any references to a "default constructor" in the C# spec
other than one provided by the compiler.
No managed language compiler I know of,will generate a default
constructor. Check [1] [2] and [3] so see what ECMA says about this.

If we're quoting ECMA, we should also quote the C# spec (ECMA 334)
which doesn't say that the compiler will generate a default constructor
for value types, but which *does* say that "every struct implicitly has
a parameterless instance constructor, which always returns the value
that results from setting all value type fields to their default
value". (2nd edition)

So, ECMA states that C# structs have a default (implicit) constructor.
As I've said in another post, I think that's reasonable for the C# spec
to define in terms of keeping C# itself consistent, even though no
actual IL parameterless constructor is generated or called.

That's what I've been trying to say. C# is not the same as the IL
code generated. You can't work backwards from IL and say this or that
about C#, although it proves useful to see what's under the hood, so I
understand Willy's desire to do so, such as to find that static
classes are sealed and abstract (although they cannot be made from C#
in that manner).

Zytan
 
Z

Zytan

It depends on what documents you reading, there is no consistent definition of a "default
constructor", some call a "default user defined constructor" a default constructor" while
others don't make the distinction. Anyway, you got a point, I also prefer to call the
compiler generated constructor the "default constructor".

I just assumed "default constructor" = a constructor implicitly
created, that I didn't make.
Which is "wrong" also, the C# compiler does not produce a "default constructor" for value
types, that is, there is no .ctor() emitted in IL.

Whoa. Now ECMA is wrong? Willy, this is my point: Just because IL
shows no .ctor() call it doesn't mean C# doesn't have a constructor.

For example, and you know more about IL than me, but I just recently
found out that a static C# class is really sealed + abstract in IL (I
hope I got that right). Now, if you look at the IL, and see that it
is sealed and abstract, you cannot then say that C# has no static
classes because the IL shows it is *actually* under the hood sealed
and abstract.

I know this example is not quite a proper analogy, but I hope you get
the point.

Zytan
 
Z

Zytan

Personally, I think it's about context. From the context of C#, I think
you end up with a consistent approach if you consider all value types
to have an implicit parameterless constructor which initialises
everything to zero. It means you don't have to specify that:

int x = new int();

actually isn't calling a constructor. It basically makes life easier
from the point of view of someone who is only interested in C# rather
than the guts, without actually doing *much* conceptual damage.

Now, at the CLR level, it *isn't* calling a constructor, it's calling
initobject (or something similar - I can't remember offhand). But at
the C# level, I think it's reasonable to treat it as a parameterless
constructor.

Thanks Jon, you've explained in much better words what I've been
trying to say. Maybe I will step out of this discussion, since
evidently, I am not making my point very clear.

Zytan
 
Z

Zytan

I'm afraid, we will have to agree to disagree :-(.
C# (the compiler) doesn't emit a parameterless constructor (aka "default constructor"), and
obviously, doesn't emit a call to a parameterless constructor either, instead, an"initobj
.."[1] is emitted to initialize a value type.

But, isn't there where the disagreement occurs? You seem to think the
'truth', and I respect your desire to find it, is at the low level,
which I can also respect (since that's what's *actually* happening!).
But, consider that the low level code could remove the need to call a
default constructor that does nothing useful (since the bytes are
already zeroed out), and thus, the low level code would be
inconsistent with what is conceptually there at the C# level.
Why it's okay to say that "from the C# point of view, value types have default parameterless
constructors.", is beyond me, really. Honestly, this confuses people as it confused the OP,
hence it's question.

See above. It's a view point. I can see from your point of view, as
well. Try and look from my view point, from C#'s view point. It
really shouldn't be beyond you. I don't think I am confused. I don't
think you are. It's just two viewpoints.
This brings us back to the OP's question - how can I prevent this to happen - , well the
answer is you can't unless you switch to another language like ILAsm.

I am fine that I cannot prevent it. It was just a curiosity.

Thanks,

Zytan
 
Z

Zytan

If there were no way to create structs in a default manner, then it
would be impossible to safely create an array of arbitrary length of
such structs, and similarly, for the same reason, it would be impossible
to store such structs in something like a
List<MyStructWithNoDefaultishCtor> (because that would need some way
creating an array of such structs).

Very true.
You should design your struct so that zeros are meaningful values. Don't
forget that it's only the fields that are initialized to zero, so the
external behaviour of the struct, via properties and methods, can be
anything you want it to be.

Yes, of course.
If it's still too much of a problem, don't use structs. Use classes.
True.


Take a chill pill, man!

Hey, I was trying to find the source of the disagreement. If it was
opinion based and emotion, then the conversation was going to go
nowhere.

Zytan
 
W

Willy Denoyette [MVP]

Zytan said:
So, basically, it is regarded as a default constructor. It's just
that all it does it zero things out, so it most cases, it needn't be
called, so it isn't called. Because of this, it cannot be replaced.
That's why C# doesn't allow a parameterless struct constructor. If
none of the above were true, there would be no issue with C# allowing
the coding of a parameterless default constructor. I think this
proves pretty conclusively that struct's have default constructors.

No. Its' not that structs can't have parameterless constructors, it's the C# compiler that
doesn't emit such constructor (called a "default constructor"), and doesn't allow you to
define a parameterless constructor in C#.
The zero initialization you are noticing and what you call a "default constructor", comes
from;
1) the 'initlocals 'flag set in the method metadata by the C# compiler, this flag is a hint
for the JIT to initialize all local variables to zero, so, a local variable holding a struct
is zero initialized because of a default action on all the locals.
2) for embedded structs, it comes from the fact that the memory allocated for a reference
instance on the GC heap is zeroed by the GC/memory allocator, but not by a constructor.

Now, if you continue to call this a "default constructor" or a "conceptual constructor", no
problem for me. But I know they are not constructors "pure sang".


I can see why people, being pendantic (which is often needed in
programming concepts, it's not a bad thing) think there is no default
cosntructor, because none is specifically called in the byte code that
results. But, we really are talking about the C# language here, not
the resulting byte code.

I'm not talking about byte code ether, I'm talking about what is produced by the #C
compiler, that is, no "default constructor".
Just because something it optimized out, it

This is not about optimizing out.
doesn't mean it's not there (conceptually, in terms of the language
itself). We've just been speaking two languages. None the less, I
think MSDN is 100% correct in its position that structs have default
constructors, and if they didn't, we'd be able to make our own
parameterless constructors, which we can't.

I have to disagree, with what MSDN says, the page you are refering to is "too strong worded,
and confusing.

<snip
Structs cannot contain explicit parameterless constructorsI would agree when there was written, "C# Structs cannot contain...". Structs is too broad a
term here, see later for a sample that proves that structs (aka value types) can have
"explicit parameterless constructors" .

and here:
<snip
Each struct already has a default constructor that initializes the object to zero.I would agree when there was written:
Each C# struct is already initialized to zero. Therefore the ......


To illustrate my point consider following sample written in ILasm (just another (low level)
language on the platform) which allows you to declare a parameterless constructor.

//compile: ilasm /out:mystruct.dll /dll mystruct.il
..assembly extern mscorlib {}
..assembly mystruct{}
..class public sequential ansi sealed beforefieldinit S
extends [mscorlib]System.ValueType
{
.field public int32 ii
.field public int64 l
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
ldarg.0
ldc.i4.2 // store 2 in field l
conv.i8
stfld int64 S::l
ret
}
}

Do yourself a favor, and compile it and look at the IL using ildasm, you'll notice the
parameterless constructor .ctor (which is not emitted by C# for structs).

Now let's try to use this value type from C# (or from VB or C++/CLI whatever):

// comile: csc /r:mystruct.dll thisfile.cs
class Program
{
static void Main()
{
S ms = new S();
Console.WriteLine("{0} - {1}", ms.ii, ms.l);
}
}

this will output 0 - 2, you see that C# supports calling parameterless constructors, only
that it doesn't allow to produce one, and that's what I'm trying to say since days now.
So you have problem is solved - define your structs in ILAsm if you want a parameterless
constructor.

Willy.
 
Z

Zytan

So, basically, it is regarded as a default constructor. It's just
No. Its' not that structs can't have parameterless constructors, it's the C# compiler that
doesn't emit such constructor (called a "default constructor"), and doesn't allow you to
define a parameterless constructor in C#.
The zero initialization you are noticing and what you call a "default constructor", comes
from;
1) the 'initlocals 'flag set in the method metadata by the C# compiler, this flag is a hint
for the JIT to initialize all local variables to zero, so, a local variable holding a struct
is zero initialized because of a default action on all the locals.
2) for embedded structs, it comes from the fact that the memory allocated for a reference
instance on the GC heap is zeroed by the GC/memory allocator, but not by a constructor.

Ok, yes, I know something else zeroes the memory. What I am saying is
that because of these other things that zeor the memory, there is no
need to call a constuctor that does so, thus, the byte code or IL code
or whatever it is that is created from the C# code, doesn't explicitly
call a constructor. It would be foolish for two reasons: 1. to repeat
the zeroing out, and 2. it's just plain slow.

Now, because the code that is created / compiled from the C# code,
whether its byte code or IL code, whatever it is called, I have no
idea, but my point is, just because whatever created this code is
smart enough to realize, hey, yeah, don't call a constructor for all
basic value types and all structs since they are already zeroed out by
the methods you've described, it doesn't *mean* that the C# language
doesn't have a constructor.

What I am trying to say is: Everything I am saying could be
absolutely true, and the result is precisely what you see: no
constructor calls in the IL.
Now, if you continue to call this a "default constructor" or a "conceptual constructor", no
problem for me. But I know they are not constructors "pure sang".

It is very convenient to call it a default constructor, because
everything flows into place with that thought.

And, yes, I can see that it does from your perspective, too.

So, it's basically up to the language designers to say what it what.

Given the evidence, I highly suspect that default constructors for
struct is a concept that they created.
I'm not talking about byte code ether, I'm talking about what is produced by the #C
compiler, that is, no "default constructor".

What? Isn't "what is produced by the #C compiler" == "byte code"? If
not, replace "byte code" with "IL". Or replace it with whatever
should be there. Whatever that is called, that's what I'm talking
about, and excuse my lack of knowledge with the terminology. I will
use "IL" from now, assuming that's correct.

Yes, IL has no constructor call. I know. You've proven that.
This does not mean C# doesn't have a constructor there. Just because
the compiler is smart enough to not make it have one, then it's ok.
It's like constructors for basic data types in C++, you can call them,
but you know that down in the assembly code that is made, there is no
function call to any constructor. It just stores the value right into
memory. It doesn't mean the constructor doesn't exist, and in fact,
you can initialize a variable with constructor like syntax, which
shows at the C++ level, it does exist. IL is not C#. I guess that's
the issue. It's like you're looking under the hood, and seeing
'what's really there', and you're saying 'hey, no constructor call!
thus, C# structs have no constructor'.
This is not about optimizing out.

If C# structs have default constructors, then, yes, they are.
I have to disagree, with what MSDN says, the page you are refering to is "too strong worded,
and confusing.

<snip
Structs cannot contain explicit parameterless constructors

I would agree when there was written, "C# Structs cannot contain...". Structs is too broad a
term here, see later for a sample that proves that structs (aka value types) can have
"explicit parameterless constructors" .

Do you mean that basic value types are structs? I think that's a case
where C# says they are structs, but you know deep down inside, they
are not anything but a memory address. That's how digging down can
lead you to the wrong conclusion about the high level language.
To illustrate my point consider following sample written in ILasm (just another (low level)
language on the platform) which allows you to declare a parameterless constructor.

//compile: ilasm /out:mystruct.dll /dll mystruct.il
.assembly extern mscorlib {}
.assembly mystruct{}
.class public sequential ansi sealed beforefieldinit S
extends [mscorlib]System.ValueType
{
.field public int32 ii
.field public int64 l
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
ldarg.0
ldc.i4.2 // store 2 in field l
conv.i8
stfld int64 S::l
ret
}

}

Do yourself a favor, and compile it and look at the IL using ildasm, you'll notice the
parameterless constructor .ctor (which is not emitted by C# for structs).

Yes, I know, I trust you, I don't need to compile this. I know that IL
makes a parameterless constructor which C# does not 'emit' into IL
code. I know this.

What I am saying is that doesn't matter. It matters no more than the
function call that was optimized out of existance, so it doesn't
appear in IL. You'd never say that function didn't exist. The IL
doesn't have to match C#. As long as it does what actual, non-
optimized, stupidly created IL could would do based precisely on the
C# syntax, it's ok. Speed is an issue, so basic types do not call
constructors, just as they don't in C++. It doesn't mean they are not
conceptually there at the *high level language*.
Now let's try to use this value type from C# (or from VB or C++/CLI whatever):

// comile: csc /r:mystruct.dll thisfile.cs
class Program
{
static void Main()
{
S ms = new S();
Console.WriteLine("{0} - {1}", ms.ii, ms.l);
}
}

this will output 0 - 2, you see that C# supports calling parameterless constructors, only
that it doesn't allow to produce one, and that's what I'm trying to say since days now.

I don't think this is a fair call. You're creating non-C# code. Yes,
I agree that C# doesn't let you make parameterless constructor.
Conceptually, this is because the optimizied IL code doesn't call one,
and couldn't possibly call your own in a decent enough way that the
designers could guarantee it be called, so the language denies your
right. I could make assembly code do anything, and call it from a
high level language, but that really says nothing about the high level
language. I could make C# call a function that does things beyond
what the language allows, but it doesn't mean C# 'knows' about this.
You're stepping out of bounds.

Again, your position is totally about the IL code generated. If you
think whatever IL code is generated IS what C# IS, then you're taking
a side that's impossible to argue against, because I'm talking about
C#, not the IL code. It is pointless to continue if this is the
position you hold, which I believe you've clearly shown. I don't
follow that logic, since the IL code can be vastly different. Ffor
instance, what do you say about C# static classes when looking at IL
code? Shouldn't you also hold C# to what the IL code is generated in
those cases, as well? It seems illogical to me, since you have to
pick and choose when you want to follow that stance or not. In terms
of default struct constructors existing, every piece fits. IL code is
out of bounds. If you pick that, why can't I go one step further and
start talking assembly, and say C# only supports JMP and CALL
instructions for program flow? I can't. It's out of bounds.

Zytan
 
J

Jon Skeet [C# MVP]

Sure not, let's talk about the CLI then, it's still the "Common
Language ..." which is dominant and indicative, but still it doesn't
mean that C# is the only language supported.

Absolutely - but that's completely beside my point. C# could target
another platform which *did* require the compiler to actually generate
a parameterless constructor for value types.

C# is just the language - *not* the compiler output.
I'm afraid, we will have to agree to disagree :-(. C# (the compiler)
doesn't emit a parameterless constructor (aka "default constructor"),
and obviously, doesn't emit a call to a parameterless constructor
either, instead, an"initobj .."[1] is emitted to initialize a value
type.

Everywhere in your paragraph above, you're thinking of "constructor"
from an IL/CLI point of view - because it's all "what the compiler
outputs" which *is* IL. That's independent of what the C# *language*
says.

It would probably be clearer to talk about the compiler as the
"C#/CLI" compiler - it's not the only possible C# compiler.
Why it's okay to say that "from the C# point of view, value types
have default parameterless constructors.", is beyond me, really.
Honestly, this confuses people as it confused the OP, hence it's
question.

It's okay to say that because it means the C# spec doesn't need to
introduce a completely different concept for calls like:

int x = new int();

What would you call the above, in terms already described in the C#
spec?
Note, however, that an instance of a value type, can have a
parameterless constructor.

In *IL* constructor, but not a *C#* constructor. They're different
things, just as a static constructor in C# is not the same thing as an
IL type initializer.
You can write valid value classes having a parameterless constructor
IL (using ILAsm). All you need is a "call instance void
SomeValue::.ctor()" to create an instance of the value type (here
SomeValue). The only drawback is that it's slower to initialize an
instance using this method than a simple initobj or relying on
"initlocals".

However, you can't do that in C#, and wouldn't be able to if you used a
C# compiler targetting a different platform, either.
 
J

Jon Skeet [C# MVP]

Willy Denoyette said:
It depends on what documents you reading, there is no consistent
definition of a "default constructor", some call a "default user
defined constructor" a default constructor" while others don't make
the distinction. Anyway, you got a point, I also prefer to call the
compiler generated constructor the "default constructor".

Yes, it's a shame it's not explicitly defined, only used.
Which is "wrong" also, the C# compiler does not produce a "default
constructor" for value types, that is, there is no .ctor() emitted in
IL.

As I said, there's nothing in the spec which says the C# compiler will
generate a default constructor for value types - just that (from a C#
point of view) every value type has an implicit constructor.

Put it this way: suppose the CLI (which is independent of C#) *did*
require the compiler to output a parameterless constructor, and instead
of initobj, that constructor were used. What bit of C# as a language
would change? Nothing.

You need to distinguish between the IL constructor and the constructor
as defined and used in C# code.
ECMA-334 also says that such constructor "returns" an initialized
value type! Now, how can something that doesn't exist return
something, more, how can you ever call such thing?

Because it exists conceptually in C#, and the compiler makes sure that
the semantics match the specification. What goes on at the CLI level is
outside the scope of the C# spec.
All what the C# compiler does in this case is:

Irrelevant. The C# compiler just makes the visible semantics match the
specification.
Agreed, but the more you dive into the ECMA specs, the more apparent
the inconsistencies and contradictions become, this confuses some
people as you now.

Some of the inconsistencies have certainly confused people - this is
the first time I remember this particular one coming up.
 
W

Willy Denoyette [MVP]

Zytan said:
Ok, yes, I know something else zeroes the memory. What I am saying is
that because of these other things that zeor the memory, there is no
need to call a constuctor that does so, thus, the byte code or IL code
or whatever it is that is created from the C# code, doesn't explicitly
call a constructor. It would be foolish for two reasons: 1. to repeat
the zeroing out, and 2. it's just plain slow.

Now, because the code that is created / compiled from the C# code,
whether its byte code or IL code, whatever it is called, I have no
idea, but my point is, just because whatever created this code is
smart enough to realize, hey, yeah, don't call a constructor for all
basic value types and all structs since they are already zeroed out by
the methods you've described, it doesn't *mean* that the C# language
doesn't have a constructor.

What I am trying to say is: Everything I am saying could be
absolutely true, and the result is precisely what you see: no
constructor calls in the IL.


It is very convenient to call it a default constructor, because
everything flows into place with that thought.

And, yes, I can see that it does from your perspective, too.

So, it's basically up to the language designers to say what it what.

Given the evidence, I highly suspect that default constructors for
struct is a concept that they created.


What? Isn't "what is produced by the #C compiler" == "byte code"? If
not, replace "byte code" with "IL". Or replace it with whatever
should be there. Whatever that is called, that's what I'm talking
about, and excuse my lack of knowledge with the terminology. I will
use "IL" from now, assuming that's correct.

Yes, IL has no constructor call. I know. You've proven that.
This does not mean C# doesn't have a constructor there.

WHERE is he? if there is one you should be able to show me one.

Just because
the compiler is smart enough to not make it have one, then it's ok.
It's like constructors for basic data types in C++, you can call them,
but you know that down in the assembly code that is made, there is no
function call to any constructor. It just stores the value right into
memory. It doesn't mean the constructor doesn't exist, and in fact,
you can initialize a variable with constructor like syntax, which
shows at the C++ level, it does exist. IL is not C#. I guess that's
the issue. It's like you're looking under the hood, and seeing
'what's really there', and you're saying 'hey, no constructor call!
thus, C# structs have no constructor'.
This is not about optimizing out.

If C# structs have default constructors, then, yes, they are.
I have to disagree, with what MSDN says, the page you are refering to is "too strong
worded,
and confusing.

<snip
Structs cannot contain explicit parameterless constructors

I would agree when there was written, "C# Structs cannot contain...". Structs is too
broad a
term here, see later for a sample that proves that structs (aka value types) can have
"explicit parameterless constructors" .

Do you mean that basic value types are structs? I think that's a case
where C# says they are structs, but you know deep down inside, they
are not anything but a memory address. That's how digging down can
lead you to the wrong conclusion about the high level language.
To illustrate my point consider following sample written in ILasm (just another (low
level)
language on the platform) which allows you to declare a parameterless constructor.

//compile: ilasm /out:mystruct.dll /dll mystruct.il
.assembly extern mscorlib {}
.assembly mystruct{}
.class public sequential ansi sealed beforefieldinit S
extends [mscorlib]System.ValueType
{
.field public int32 ii
.field public int64 l
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
ldarg.0
ldc.i4.2 // store 2 in field l
conv.i8
stfld int64 S::l
ret
}

}

Do yourself a favor, and compile it and look at the IL using ildasm, you'll notice the
parameterless constructor .ctor (which is not emitted by C# for structs).

Yes, I know, I trust you, I don't need to compile this. I know that IL
makes a parameterless constructor which C# does not 'emit' into IL
code. I know this.

What I am saying is that doesn't matter. It matters no more than the
function call that was optimized out of existance,

There is no function call optimized away, see later.

so it doesn't
appear in IL. You'd never say that function didn't exist. The IL
doesn't have to match C#. As long as it does what actual, non-
optimized, stupidly created IL could would do based precisely on the
C# syntax, it's ok. Speed is an issue, so basic types do not call
constructors, just as they don't in C++. It doesn't mean they are not
conceptually there at the *high level language*.

You are wrong by comparing managed code to native C++, the object model is too different.
I don't think this is a fair call. You're creating non-C# code. Yes,
I agree that C# doesn't let you make parameterless constructor.
Conceptually, this is because the optimizied IL code doesn't call one,

No , the C# compiler doesn't create the IL for a constructor method, AND (obviously) does
not create a call to this constructor, but this is not about optimizing away the call.

Again, the C# compiler:

1) set's the 'initonly ' flag per default in the methods metadata, that means that the JIT
compiler (and not the C# compiler) will have to produce code to initialize the stack frame
at zero, and this for ALL variables on the stack frame regardless their type.
2) the runtime *initializes* the GC heap space, to hold reference instances, to zero, that
means that an embedded value type will have it's fields at zero per default. This is a
runtime and in no way a language feature.
3) does NOT emit a public parameterless constructor method for the value type, which is
called a "default constructor",and obviously,
4 does not emit a "call" to the (non existent) "constructor" in IL, instead he emits a
"initobj", which is optimized away by the JIT as he has knowlegde of 1 and 2 and will take
advantage of it.

Now, C# takes advantage of what happens as a result of 1 and/or 2, so it doesn't need to
emit IL for a "default constructor" and for a call to this constructor, in order to
*initialize* the object fields to their default value.
Now this (1 & 2) is what msdn and some of you guys call the "default constructor", well I'm
sorry but this is not what I call a constructor. Call it an 'initializer' or 'conceptual
constructor' but not a "default constructor" (which isn't such "thing" , as per Jon's
and couldn't possibly call your own in a decent enough way that the
designers could guarantee it be called, so the language denies your
right. I could make assembly code do anything, and call it from a
high level language, but that really says nothing about the high level
language. I could make C# call a function that does things beyond
what the language allows, but it doesn't mean C# 'knows' about this.
You're stepping out of bounds.

Again, your position is totally about the IL code generated.


But , there is no IL produced by the C# compiler that possibly could be called a "default
constructor". see above.
And that's exactly my point about why msdn is wrong.
Look at the ECMA specs for C++/CLI which produces the exact same IL as C#, the spec says:
[...value classes do not support user-defined destructors, finalizers, default constructors,
....],
value classes are the same a structs in C#, here is said no ... default constructors...but
not because there is already such "thing".


If you
think whatever IL code is generated IS what C# IS, then you're taking
a side that's impossible to argue against, because I'm talking about
C#, not the IL code.
I'm talking about what a C# compiler produces, the C# language itself as no
notion/definition of "default constructor", this is something that is emitted by the
compiler. So what makes you think I'm not talking about C#?

It is pointless to continue if this is the
position you hold, which I believe you've clearly shown. I don't
follow that logic, since the IL code can be vastly different. Ffor
instance, what do you say about C# static classes when looking at IL
code?

What have static class to do with this discussion?

Shouldn't you also hold C# to what the IL code is generated in
those cases, as well? It seems illogical to me, since you have to
pick and choose when you want to follow that stance or not. In terms
of default struct constructors existing, every piece fits. IL code is
out of bounds. If you pick that, why can't I go one step further and
start talking assembly, and say C# only supports JMP and CALL
instructions for program flow? I can't. It's out of bounds.
Who's talking about machine code? machine code is what gets executed by the processors, IL
is not, IL is byte code, it's the source code for the VM (the JIT), everything in .NET
translates into IL.
Note however, that the sample I showed you is not IL, it's a higher level language which is
called "ILAsm", which compiler produces IL just like all other compilers who target the CLR.
Note that could have produced the exact same value type using C#!

Anyway, I have not the intention to continue this discussion, so we'll have to agree to
disagree.

Willy.
 
J

Jon Skeet [C# MVP]

Willy Denoyette said:
WHERE is he? if there is one you should be able to show me one.

Sure - I can show it, by calling it, but *only* in C#. Just because it
exists as far as C# is concerned doesn't mean it has to exist in IL.

Here's the code:

int i = new int();

Now, we both know that isn't calling a constructor in IL - but from a
C# point of view, it is. It's calling the implicit parameterless
constructor which sets all the fields to 0/null/etc.
But , there is no IL produced by the C# compiler that possibly could be called a "default
constructor". see above.

Where does it say that the C# compiler *produces* a default
constructor? It just says that there is an *implicit* parameterless
constructor. And value types behave *from a C# point of view* exactly
*as if* they had a parameterless constructor in the IL.

The IL itself is outside the scope of the C# spec - the C# spec only
talks about what is allowed within C# and what will happen when the
produced code is executed. There's nothing to say that a C# compiler
has to produce IL at all.
And that's exactly my point about why msdn is wrong.

Note that it's not just MSDN - it's the ECMA C# spec itself that claims
that value types have an implicit parameterless constructor.
Look at the ECMA specs for C++/CLI which produces the exact same IL
as C#, the spec says: [...value classes do not support user-defined
destructors, finalizers, default constructors, ...], value classes
are the same a structs in C#, here is said no ... default
constructors...but not because there is already such "thing".

Do you treat ECMA specs as authoritative or not? If so, then the C#
spec is quite clear. If not, quoting a different one doesn't prove
anything.
 
W

Willy Denoyette [MVP]

Jon Skeet said:
Sure - I can show it, by calling it, but *only* in C#. Just because it
exists as far as C# is concerned doesn't mean it has to exist in IL.

Here's the code:

int i = new int();

Here you show a "constructor" call, not the actual constructor. What the C# compiler does
here is, emit IL (a load and a store) to set the evaluation stack slot, reserved for the int
to 0 (possibly optimized away by the JIT), now do you call this IL a "constructor", a
"default constructor "or a "conceptual" constructor or what? This is what I call an
initializer and there is always one produced (or through IL or by the JIT depending on the
'initlocals' flag).
What I call a "constructor" is what I've showed with the ILAsm sample, here the compiler
emit's MSIL and injects a .ctor method in the type's method table, you can see this .ctor
entry at run-time using windbg with sos.dll.
Now, we both know that isn't calling a constructor in IL - but from a
C# point of view, it is. It's calling the implicit parameterless
constructor which sets all the fields to 0/null/etc.

Conceptually it looks like a constructor, but actually it isn't one
Where does it say that the C# compiler *produces* a default
constructor? It just says that there is an *implicit* parameterless
constructor. And value types behave *from a C# point of view* exactly
*as if* they had a parameterless constructor in the IL.
The C# reference <http://msdn2.microsoft.com/en-us/library/x2xcf8ft(vs.80).aspx > says:
<snip
Each struct already has a default constructor that initializes the object to zero.
Therefore, the constructors that you can create for a struct must take one or more
parameters.
My question is where does this "default constructor " comes from?
You know perfectly well that the *thing* that "initializes the object to zero" is the JIT
compiler, who see the "initlocals" attribute in the method metadata (set by the C#
compiler), and generates native code to set all "locals" stack locations to zero. For an
embedded struct (value type) it doesn't do anything specific.


The IL itself is outside the scope of the C# spec - the C# spec only
talks about what is allowed within C# and what will happen when the
produced code is executed. There's nothing to say that a C# compiler
has to produce IL at all.

That's not my point. My point is that C# says:
1 That there is a "default constructor", and this is what I consider outside the scope of
the spec, this is an implementation detail, and it's exactly this detail which I'm fighting.
2 That this is the reason why a user defined parameterless constructor is not allowed, which
is not the real reason.
Note that it's not just MSDN - it's the ECMA C# spec itself that claims
that value types have an implicit parameterless constructor.

MSDN and ECMA have the same source, I can show you paragraphs which are identical, only
thing is that ECMA is a bit cleaned up, both are written by the same technical writers, I
don't tell you secrets I assume.
Look at the ECMA specs for C++/CLI which produces the exact same IL
as C#, the spec says: [...value classes do not support user-defined
destructors, finalizers, default constructors, ...], value classes
are the same a structs in C#, here is said no ... default
constructors...but not because there is already such "thing".

Do you treat ECMA specs as authoritative or not? If so, then the C#
spec is quite clear. If not, quoting a different one doesn't prove
anything.

Yes I do, and I didn't say ECMA (or MSDN) wasn't clear, I said it was "inacurate" and
"inconsistent" across different ECMA documents depending on the language.
Therefore, I prefer what is said in the C++/CLI ECMA spec.:
[...value classes do not support user-defined destructors, finalizers, default
constructors,...], see - no default constructors supported- , however they don't say that's
it's because value classes already have such thing.
ECMA 372 (C++/CLI) is written long after ECMA-334, and by other people, and that's why I
said 334 shows it's age.

I also prefer the way (syntactically) you declare value types in C++/CLI, no big deal,
different languages different syntax, I can live with that. (I live in a country who has
three official languages, I speak all three of them, so, it's part of my culture).

Her is what I mean.

public value struct S
{
public: int i;
}
....
S s;
s.i = 123;
....

constrast this with C#

public struct S
{
public int i;
}
...

S s; // valid, this emits the "initobj", here the object is guaranteed to be
initialized.
s.i = 123; // this is not accepted, the compiler barfs.
s = new S(); // this is needed to please the compiler, but doesn't produce any MSIL.
s.i = 123;

Willy.
 
J

Jon Skeet [C# MVP]

Willy Denoyette said:
Here you show a "constructor" call, not the actual constructor. What
the C# compiler does here is, emit IL (a load and a store) to set the
evaluation stack slot, reserved for the int to 0 (possibly optimized
away by the JIT), now do you call this IL a "constructor", a "default
constructor "or a "conceptual" constructor or what? This is what I
call an initializer and there is always one produced (or through IL
or by the JIT depending on the 'initlocals' flag).

What the C# compiler does is irrelevant to what kind of C# expression
is involved here.

Everyone agrees that in IL there is no parameterless constructor.
That's not the same thing as there not being a parameterless
constructor at the C# level of looking at things.
What I call a "constructor" is what I've showed with the ILAsm
sample, here the compiler emit's MSIL and injects a .ctor method in
the type's method table, you can see this .ctor entry at run-time
using windbg with sos.dll.

Then you're talking in CLI terms, not C# terms. It's vital to
distinguish between the two.
Conceptually it looks like a constructor, but actually it isn't one

At the IL level, which isn't what the C# spec describes.
The C# reference <http://msdn2.microsoft.com/en-us/library/x2xcf8ft(vs.80).aspx > says:
<snip
Each struct already has a default constructor that initializes the object to zero.
Therefore, the constructors that you can create for a struct must take one or more
parameters.

My question is where does this "default constructor " comes from?

It's of no interest to me (in this discussion) how the C# compiler
achieves the effect of implementing the C# spec. The important thing is
what the spec states, which is that there is a parameterless
constructor.
You know perfectly well that the *thing* that "initializes the object
to zero" is the JIT compiler, who see the "initlocals" attribute in
the method metadata (set by the C# compiler), and generates native
code to set all "locals" stack locations to zero. For an embedded
struct (value type) it doesn't do anything specific.

Agreed, but irrelevant.
That's not my point. My point is that C# says:
1 That there is a "default constructor", and this is what I consider
outside the scope of the spec, this is an implementation detail, and
it's exactly this detail which I'm fighting.

There *is* a default constructor from the point of view of what you can
do in C#. The semantics are consistent with there being a default
constructor. If the CLI were different, and the C# compiler *did* have
to generate a parameterless constructor, C# as a language wouldn't have
to change.
2 That this is the reason why a user defined parameterless
constructor is not allowed, which is not the real reason.

Well, that can be the reason from the C# spec's point of view. It would
prohibit a parameterless constructor being declared even when
targetting a platform where such a constructor would be feasible, make
sense etc.
MSDN and ECMA have the same source, I can show you paragraphs which
are identical, only thing is that ECMA is a bit cleaned up, both are
written by the same technical writers, I don't tell you secrets I
assume.

Of course not. A compiler error isn't the same as the spec, of course -
but I see that the spec does in fact contain the same kind of logic.
Yes I do, and I didn't say ECMA (or MSDN) wasn't clear, I said it was
"inacurate" and "inconsistent" across different ECMA documents
depending on the language.

Inconsistent I would certainly agree with, although I don't think
consistency between documents which are describing things is always
necessary. Preferable, generally, but not absolutely necessary.

Inaccurate I find harder to swallow. The C# spec is defining the
behaviour of a C# program, and I don't see any inaccuracy in there.
Therefore, I prefer what is said in the C++/CLI ECMA spec.: [...value
classes do not support user-defined destructors, finalizers, default
constructors,...], see - no default constructors supported- , however
they don't say that's it's because value classes already have such
thing. ECMA 372 (C++/CLI) is written long after ECMA-334, and by
other people, and that's why I said 334 shows it's age.

It's fine to prefer one spec to another, but I don't see that it makes
the C# spec inaccurate in defining the C# language, which is all the C#
spec is meant to do.
I also prefer the way (syntactically) you declare value types in C++/CLI, no big deal,
different languages different syntax, I can live with that. (I live in a country who has
three official languages, I speak all three of them, so, it's part of my culture).

Her is what I mean.

public value struct S
{
public: int i;
}
...
S s;
s.i = 123;
...

constrast this with C#

public struct S
{
public int i;
}
..

S s; // valid, this emits the "initobj", here the object is guaranteed to be
initialized.
s.i = 123; // this is not accepted, the compiler barfs.
s = new S(); // this is needed to please the compiler, but doesn't produce any MSIL.
s.i = 123;

Um, no, that's not required. Try compiling this:

public struct Foo
{
public int i;
}

class Test
{
static void Main()
{
Foo f;
f.i = 123;
}
}

That compiles with no warnings at all.
What you can't do is *read* a field until all fields have definitely
been assigned a value - and I agree, that's slightly silly given that
they will all have been definitely assigned a value of 0. Under the
CLI, that is - which isn't what the C# spec explicitly targets.

That's a difference between the C# spec and the C++/CLI spec - the
C++/CLI spec can make assumptions based on the CLI behaviour, whereas
the C# spec tries to stay at least slightly agnostic.
 
W

Willy Denoyette [MVP]

Jon Skeet said:
What the C# compiler does is irrelevant to what kind of C# expression
is involved here.

Everyone agrees that in IL there is no parameterless constructor.
That's not the same thing as there not being a parameterless
constructor at the C# level of looking at things.


Then you're talking in CLI terms, not C# terms. It's vital to
distinguish between the two.


At the IL level, which isn't what the C# spec describes.


It's of no interest to me (in this discussion) how the C# compiler
achieves the effect of implementing the C# spec. The important thing is
what the spec states, which is that there is a parameterless
constructor.


Agreed, but irrelevant.



There *is* a default constructor from the point of view of what you can
do in C#. The semantics are consistent with there being a default
constructor. If the CLI were different, and the C# compiler *did* have
to generate a parameterless constructor, C# as a language wouldn't have
to change.


Well, that can be the reason from the C# spec's point of view. It would
prohibit a parameterless constructor being declared even when
targetting a platform where such a constructor would be feasible, make
sense etc.


Of course not. A compiler error isn't the same as the spec, of course -
but I see that the spec does in fact contain the same kind of logic.


Inconsistent I would certainly agree with, although I don't think
consistency between documents which are describing things is always
necessary. Preferable, generally, but not absolutely necessary.

Inaccurate I find harder to swallow. The C# spec is defining the
behaviour of a C# program, and I don't see any inaccuracy in there.
It does'nt actually decribes behaviour, it goes into some detail which is inaccurate. As I
said, they should have used a different terminology instead of talking about something,
called a *constructor*, that has wel defined semantics on the CLI/CLR.
This from ECMA-334:

<All value types implicitly declare a public parameterless instance constructor called the
default constructor.
The default constructor returns a zero-initialized instance known as the default value for
the value type:..>

see: "implicitly ", "instance constructor", "default constructor" and "returns" a
zero-initialized instance, and this is what I call inaccurate and confusing. Many developers
I met have been confused by terms like above, finally, I explained that they should forget
about this "default constructor" that "returns" an instance of a value type, what they
should know is that they have an zero initialized instance available at the point of
declaration.
Therefore, I prefer what is said in the C++/CLI ECMA spec.: [...value
classes do not support user-defined destructors, finalizers, default
constructors,...], see - no default constructors supported- , however
they don't say that's it's because value classes already have such
thing. ECMA 372 (C++/CLI) is written long after ECMA-334, and by
other people, and that's why I said 334 shows it's age.

It's fine to prefer one spec to another, but I don't see that it makes
the C# spec inaccurate in defining the C# language, which is all the C#
spec is meant to do.
I also prefer the way (syntactically) you declare value types in C++/CLI, no big deal,
different languages different syntax, I can live with that. (I live in a country who has
three official languages, I speak all three of them, so, it's part of my culture).

Her is what I mean.

public value struct S
{
public: int i;
}
...
S s;
s.i = 123;
...

constrast this with C#

public struct S
{
public int i;
}
..

S s; // valid, this emits the "initobj", here the object is guaranteed to be
initialized.
s.i = 123; // this is not accepted, the compiler barfs.
s = new S(); // this is needed to please the compiler, but doesn't produce any MSIL.
s.i = 123;

Um, no, that's not required. Try compiling this:

public struct Foo
{
public int i;
}

class Test
{
static void Main()
{
Foo f;
f.i = 123;
}
}

That compiles with no warnings at all.


Sorry, that's what I meant to show.

In C++/CLI you can do:
..
S s;
int v = s.i ;
..

which is not posible in C#.
on the other hand, this in C++/CLI....
...
S s = gcnew S();

creates a boxed instance of S! And again this confuses those who use both (or more)
languages. I know abouth this because in my daily job I have to consult people using VB, C#
and C++ in any combination, this is not a "single language" world as you probably know Jon.

What you can't do is *read* a field until all fields have definitely
been assigned a value - and I agree, that's slightly silly given that
they will all have been definitely assigned a value of 0. Under the
CLI, that is - which isn't what the C# spec explicitly targets.

That's a difference between the C# spec and the C++/CLI spec - the
C++/CLI spec can make assumptions based on the CLI behaviour, whereas
the C# spec tries to stay at least slightly agnostic.

True, this was not such a problem when C# was the only (ignoring VB.NET as it's not an ECMA
standard) in the game. However, things have changed, and the C++/CLI tech. writers *did
read* the ECMA-334 and considered this all as confusing and, IMO incorrect because they
opted for a different text and I don't see where they are less *agnostic*.

Willy.
 
J

Jon Skeet [C# MVP]

True, this was not such a problem when C# was the only (ignoring
VB.NET as it's not an ECMA standard) in the game. However, things
have changed, and the C++/CLI tech. writers *did read* the ECMA-334
and considered this all as confusing and, IMO incorrect because they
opted for a different text and I don't see where they are less
*agnostic*.

The fact that the standard is called the "C++/CLI" spec is a bit of a
hint in my opinion that the standard specifically targets the CLI,
whereas the C# spec doesn't - it could, in theory, target a different
architecture. It's unlikely to happen, but the spec still isn't tied to
the CLI, which is why I believe it's a mistake to call something in the
C# spec "inaccurate" just because it doesn't reflect what's going on
under the hood in an implementation which *does* target the CLI.
 
Z

Zytan

Yes, IL has no constructor call. I know. You've proven that.
WHERE is he? if there is one you should be able to show me one.

Willy, it is beyond obvious you have not listened to a single thing,
in the most literal sense, that I've said about CIL and C#. (IL is
more properly called CIL, so I'll use that instead, I'm trying to use
the right terminology).

CIL is not C#.

CIL != C#.

I've already said this. Jon just showed an example of this, which
I'll post here again to show I have also been meaning the exact same
thing:

int i = new int();

There's the proof. It's calling a constructor. Now go look for it.
It wont' be in the CIL. It won't exist in the assembly code. So, you
*illogically* assume the constructor does not exist at the high
level. Yet, there it is.

There is no point in continuing this discussion. Because your entire
argument is based on a fallacy.

Imagine how frustrated you would be if you attempted to argue that C
has switch statement syntax, and I showed you the optimized assembly
code computed a singke memory address and called a single JMP
instruction to that address, to avoid numerous if/then/else style of
assembly, and claimed that the C language only has GOTO, because
that's all that exists in assembly. Imagine that. That's an analogy
of the stance you are taking. It's a fallacy.
There is no function call optimized away, see later.

I was showing an analogy. Please pay closer attention.
You are wrong by comparing managed code to native C++, the object model is too different.

That's irrelevant to the context of my point. I could use any high
level language in which lower language code is produced from the high
level language code to show the same point. What the low level has
doesn't dictate what the high level doesn't have.
Again, the C# compiler:

1) set's the 'initonly ' flag per default in the methods metadata, that means that the JIT
compiler (and not the C# compiler) will have to produce code to initialize the stack frame
at zero, and this for ALL variables on the stack frame regardless their type.
2) the runtime *initializes* the GC heap space, to hold reference instances, to zero, that
means that an embedded value type will have it's fields at zero per default. This is a
runtime and in no way a language feature.
3) does NOT emit a public parameterless constructor method for the value type, which is
called a "default constructor",and obviously,
4 does not emit a "call" to the (non existent) "constructor" in IL, instead he emits a
"initobj", which is optimized away by the JIT as he has knowlegde of 1 and 2 and will take
advantage of it.

Now, C# takes advantage of what happens as a result of 1 and/or 2, so it doesn't need to
emit IL for a "default constructor" and for a call to this constructor, in order to
*initialize* the object fields to their default value.
Now this (1 & 2) is what msdn and some of you guys call the "default constructor", well I'm
sorry but this is not what I call a constructor. Call it an 'initializer' or 'conceptual
constructor' but not a "default constructor" (which isn't such "thing" , as per Jon's
definition <I would say that a default constructor is one supplied by the compiler> - see
one of it's replies)

You're defining what C# has based on the low level code the compiler
produces. That is fundamentally flawed. Everything based on that
assumption is therefore flawed. You can show us again and again what
CIL code is produced, and it is absolutely irrelevant.
But , there is no IL produced by the C# compiler that possibly could be called a "default
constructor". see above.

Willy, you're stepping out of bounds. CIL is not C#. There is no
assembly code produced by VC++ compiler that could possibly be called
a default constructor. MOV [EAX],0. Is that a constructor? No.
Does C++ have constructors for int's? Yes.

Assembly language is not C++.
CIL is not C#.

Zytan
 
Z

Zytan

Yes, IL has no constructor call. I know. You've proven that.
Here you show a "constructor" call, not the actual constructor. What the C# compiler does
here is, emit IL (a load and a store) to set the evaluation stack slot, reserved for the int
to 0 (possibly optimized away by the JIT), now do you call this IL a "constructor", a
"default constructor "or a "conceptual" constructor or what?

The CIL code is assembly like code that does precisely the end effect
required by the C# code that was used to make it, so that the virtual
machine can change it into assembly language on the ending platform so
that this assembly code can also produce the end result that fits
precisely what the C# code desired.

I call the CIL code CIL code.
I call the assembly code assembly code.
I call the C# code a constructor, because that's what it is.
Conceptually it looks like a constructor, but actually it isn't one

Then, C# had no structs, classes, methods, variables, references,
switch statements, if/then/else statements, for loops, or anything,
because the resulting assembly language has none of that stuff. And,
no, you can't argue, because I have proof. I used a disassembler and
looked at it. No matter what you say, I'll disassemble the final
assembly and show you direct evidence that none of those C# concepts
exist in the final assembly, so while you may enjoy calling them by
their common names, I know the truth that they actually don't exist.
They *actually*, in reality, don't exist, because the *actual* code
the CPU is running has none of it. Case closed.

Seem a bit foolish?

Yeah, I would say.
The C# reference <http://msdn2.microsoft.com/en-us/library/x2xcf8ft(vs.80).aspx> says:
<snip
Each struct already has a default constructor that initializes the object to zero.
Therefore, the constructors that you can create for a struct must take one or more
parameters.

My question is where does this "default constructor " comes from?

The C# designers.
You know perfectly well that the *thing* that "initializes the object to zero" is the JIT
compiler, who see the "initlocals" attribute in the method metadata (set by the C#
compiler), and generates native code to set all "locals" stack locations to zero. For an
embedded struct (value type) it doesn't do anything specific.

No, actually, it's the MOV EAX, 0 or XOR EAX,EAX instruction. That's
what sets it to zero. I fail to see how this is relevant?

Zytan
 
W

Willy Denoyette [MVP]

Zytan said:
The CIL code is assembly like code that does precisely the end effect
required by the C# code that was used to make it, so that the virtual
machine can change it into assembly language on the ending platform so
that this assembly code can also produce the end result that fits
precisely what the C# code desired.

This doesn't answer my question.
I call the CIL code CIL code.
I call the assembly code assembly code.
I call the C# code a constructor, because that's what it is.


Then, C# had no structs, classes, methods, variables, references,
switch statements, if/then/else statements, for loops, or anything,

Did I ever say that?
because the resulting assembly language has none of that stuff. And,
no, you can't argue, because I have proof. I used a disassembler and
looked at it.

Looked at what using what?

No matter what you say, I'll disassemble the final
assembly and show you direct evidence that none of those C# concepts
exist in the final assembly,

What concepts are you talking about?? Structs, classes, etc. These C# concepts are mapped
into structured data available at run-time and visible using the right tools. Just like you
can show the assembly representation of a machine instruction using a debugger
(dissasemble), there are tools to show these concepts as they are layd-out in memory,
classes, structs, types etc.. are represented by well defined CLR data structures.

so while you may enjoy calling them by
their common names, I know the truth that they actually don't exist.

I can show you they do exist, look following is the output of a debugger command at
run-time!!

Here I dump the object instance at memory location 0000000002f41be0 (64 bit OS object on the
GC heap.)
0:000> !do 0000000002f41be0

Name: System.Text.StringBuilder
MethodTable: 000006427881fc00
EEClass: 0000064278934298
Size: 40(0x28) bytes
(C:\Windows\assembly\GAC_64\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
Fields:
MT Field Offset Type VT Attr Value Name
000006427882b808 40000b1 10 System.IntPtr 0 instance 0
m_currentThread
000006427882b328 40000b2 18 System.Int32 0 instance 2147483647
m_MaxCapacity
000006427881edb8 40000b3 8 System.String 0 instance 0000000002f41d48
m_StringValue

see the object represents a StringBuilder
And here: Dump the method table
0:000> !dumpmt 000006427882b808

EEClass: 000006427893ec58
Module: 00000642787a2000
Name: System.IntPtr
mdToken: 020000c3
(C:\Windows\assembly\GAC_64\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
BaseSize: 0x18
ComponentSize: 0x0
Number of IFaces in IFaceMap: 1
Slots in VTable: 27

You want to see the assembly for each individual method, I can show you, do you want to see
the corresponding IL? I can show you.

Want to see the GC heap, here is aprtly dump...

Number of GC Heaps: 1
generation 0 starts at 0x0000000002f41030
generation 1 starts at 0x0000000002f41018
generation 2 starts at 0x0000000002f41000
They *actually*, in reality, don't exist, because the *actual* code
the CPU is running has none of it. Case closed.

Seem a bit foolish?

No you simply showed your complete ignorance.

Yeah, I would say.


The C# designers.
Funny.


No, actually, it's the MOV EAX, 0 or XOR EAX,EAX instruction. That's
what sets it to zero. I fail to see how this is relevant?

Not exactly, these instructions zero out register eax, not a stack location, if you go down
that low level you have to be more precise.
As I said before the JIT produces code to effectively clear the *total stack area* reserved
for all locals in the frame, irrespective the type or the number of the locals, he doesn't
zero out individual "local variable" locations; he resets stack slots.
And what's more important, this happens at method entry, NOT at the point of declaration nor
at the point of the eventual constructor calls.

Say you have a method with two locals, one of type long another of type S (we are talking
about struct aren't we?):

public struct S
{
int i;
byte b;
short s;
}

void Foo {
S s;
long l;
...

}

The JIT knows (with the help of the metadata and lay-out manager) that he needs to "clear"
4 slots of stack (each 32 bit on 32 bit OS).
2 slots for the struct S and 2 slots for the long.
On 64 bit he needs to clear two slots (64 bit on 64 bit OS), one for S and one for l.
What instruction sequence the JIT produces, depends on the OS, the JIT type, the CPU
hardware (x86, X64 and IIA64) and whether JIT optimizations are enabled or not.

On 32 bit (using JIT32) above looks like:

xor eax,eax
mov dword ptr [ebp-14h],eax
mov dword ptr [ebp-10h],eax
mov dword ptr [ebp-18h],eax
mov dword ptr [ebp-1Ch],eax
.... rest of method....

but it may also look like:

pxor xmm0,xmm0
movq mmword ptr [ebp-10h],xmm0
movq mmword ptr [ebp-18h],xmm0
- See XMM SSE instructions used.

On 64 bit (using JIT64) it looks like:
xor rax,rax
mov qword ptr [rsp-18h],rax
mov qword ptr [rsp-10h],rax

- see only two mov instructions needed (reg's are 64 bit).

Note, that I'm no longer going to reply to your posts in this thread, I've spend more than
enough time on this.

Willy.
 

Ask a Question

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

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

Ask a Question

Top