I have a struct constructor to initialize all of my private (or public
readonly) fields. There still exists the default constructor that sets
them all to zero. Is there a way to remove the creation of this
implicit default constructor, to force the creation of a struct via my
constructor only?
Zytan 74 15385
On 8 Mar 2007 14:21:39 -0800, "Zytan" <zy**********@yahoo.comwrote:
>I have a struct constructor to initialize all of my private (or public readonly) fields. There still exists the default constructor that sets them all to zero. Is there a way to remove the creation of this implicit default constructor, to force the creation of a struct via my constructor only?
Zytan
Declare your own default constructor private:
struct MyStruct {
public MyStruct(int data) {
// Do stuff
}
private MyStruct() { }
}
Because you have declared your own default constructor the compiler
will not create one. Because you have declared it private no-one
except you can ever call it. This makes your struct impossible to
default construct, which will limit its use in some situations.
rossum
"rossum" <ro******@coldmail.comwrote in message
news:oc********************************@4ax.com...
On 8 Mar 2007 14:21:39 -0800, "Zytan" <zy**********@yahoo.comwrote:
>>I have a struct constructor to initialize all of my private (or public readonly) fields. There still exists the default constructor that sets them all to zero. Is there a way to remove the creation of this implicit default constructor, to force the creation of a struct via my constructor only?
Zytan
Declare your own default constructor private:
struct MyStruct {
public MyStruct(int data) {
// Do stuff
}
private MyStruct() { }
}
error CS0568: Structs cannot contain explicit parameterless constructors
David
"Zytan" <zy**********@yahoo.comwrote in message
news:11**********************@8g2000cwh.googlegrou ps.com...
>I have a struct constructor to initialize all of my private (or public
readonly) fields. There still exists the default constructor that sets
them all to zero. Is there a way to remove the creation of this
implicit default constructor, to force the creation of a struct via my
constructor only?
Zytan
Not sure what you mean here with default constructor, there is no such thing as a "default"
constructor for structs.
If you don't supply a constructor, the struct will get initialized by the runtime, such that
all its fields have their default value, that is, the memory space (f.i on the stack) taken
by the struct is set to 0. There is no way to suppress this "initialization ", which is a
good thing.
Willy.
Not sure what you mean here with default constructor, there is no such thing as a "default"
constructor for structs.
http://msdn2.microsoft.com/en-us/lib...ft(vs.80).aspx
"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."
If you don't supply a constructor, the struct will get initialized by the runtime, such that
all its fields have their default value, that is, the memory space (f.i on the stack) taken
by the struct is set to 0.
Yes, by the default constructor.
There is no way to suppress this "initialization ", which is a
good thing.
No, it's bad. Because I have a struct that contains only private data
members, as Jon Skeet wondefully pointed out is a good thing to do.
Therefore, I can only initialize those private members via constructor
(or declaration assignment -- I am not sure of the terminology of
that). Thus, if the default constructor does not disappear once I
create my own struct constructor, the caller can create a struct still
using the default constructor, setting all private / readonly fields
to 0, and they can never be changed. This is unfortunate for any
struct that has manually created constructors / properties that so
validity checking on the parameters.
(Althouhgh, for structs that have NO manually created constructors, I
agree that the default constructor that sets all fields to 0 is a good
thing.)
Zytan
Declare your own default constructor private:
>
private MyStruct() { }
http://msdn2.microsoft.com/en-us/lib...ft(vs.80).aspx
"Compiler Error CS0568
Error Message
Structs cannot contain explicit parameterless constructors
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."
Because you have declared your own default constructor the compiler
will not create one. Because you have declared it private no-one
except you can ever call it. This makes your struct impossible to
default construct, which will limit its use in some situations.
Yes, that thought works in C++ to prevent instantiation (to create
'static' classes that C++ does not support), and I thought maybe I
could do it in C#, as you've thought, as well, but it doesn't work.
Zytan
"Zytan" <zy**********@yahoo.comwrote in message
news:11**********************@64g2000cwx.googlegro ups.com...
>Not sure what you mean here with default constructor, there is no such thing as a "default" constructor for structs.
http://msdn2.microsoft.com/en-us/lib...ft(vs.80).aspx
Ever heard of mistakes in MSDN?
"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."
>If you don't supply a constructor, the struct will get initialized by the runtime, such that all its fields have their default value, that is, the memory space (f.i on the stack) taken by the struct is set to 0.
Yes, by the default constructor.
No there is no *explicit* .ctor created by the compiler for a value type as it's the case
for a class, take a look at the IL using ildasm.
>There is no way to suppress this "initialization ", which is a good thing.
No, it's bad. Because I have a struct that contains only private data
members, as Jon Skeet wondefully pointed out is a good thing to do.
Therefore, I can only initialize those private members via constructor
(or declaration assignment -- I am not sure of the terminology of
that). Thus, if the default constructor does not disappear once I
create my own struct constructor, the caller can create a struct still
using the default constructor, setting all private / readonly fields
to 0, and they can never be changed. This is unfortunate for any
struct that has manually created constructors / properties that so
validity checking on the parameters.
(Althouhgh, for structs that have NO manually created constructors, I
agree that the default constructor that sets all fields to 0 is a good
thing.)
Zytan
"Zytan" <zy**********@yahoo.comwrote in message
news:11**********************@64g2000cwx.googlegro ups.com...
>Not sure what you mean here with default constructor, there is no such thing as a "default" constructor for structs.
http://msdn2.microsoft.com/en-us/lib...ft(vs.80).aspx
"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."
>If you don't supply a constructor, the struct will get initialized by the runtime, such that all its fields have their default value, that is, the memory space (f.i on the stack) taken by the struct is set to 0.
Yes, by the default constructor.
>There is no way to suppress this "initialization ", which is a good thing.
No, it's bad. Because I have a struct that contains only private data
members, as Jon Skeet wondefully pointed out is a good thing to do.
Therefore, I can only initialize those private members via constructor
(or declaration assignment -- I am not sure of the terminology of
that). Thus, if the default constructor does not disappear once I
create my own struct constructor, the caller can create a struct still
using the default constructor, setting all private / readonly fields
to 0, and they can never be changed. This is unfortunate for any
struct that has manually created constructors / properties that so
validity checking on the parameters.
What else do you want? structs are stored on the stack (or inlined with a heap allocated
object instance), that means if the fields are not set to their default value, that they
will contain the trash that's still in the stack.
say you have:
struct S
{
int i;
SomeObject obj;
}
if S wouldn't be set to 0, SomeObject could contain an address, left on the stack from a
previous call frame possibly containing a valid pointer or even a valid object reference,
but not a reference of SomeObject type, use your imaginatio and think what could happen in
such case....
(Althouhgh, for structs that have NO manually created constructors, I
agree that the default constructor that sets all fields to 0 is a good
thing.)
No, its a perfect thin for all. If you don't want the struct to be initialized with default
values, make sure they are initialized correctly and handle the error cases.
Willy.
Not sure what you mean here with default constructor, there is no such thing as a
"default"
constructor for structs.
http://msdn2.microsoft.com/en-us/lib...ft(vs.80).aspx
Ever heard of mistakes in MSDN?
Yes. Why the attitude? It's ok to be called on something you believe
is right.
I believe MSDN is correct this time because of further evidence
explained below.
"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."
If you don't supply a constructor, the struct will get initialized by the runtime, such
that
all its fields have their default value, that is, the memory space (f.i on the stack)
taken
by the struct is set to 0.
Yes, by the default constructor.
No there is no *explicit* .ctor created by the compiler for a value type as it's the case
for a class, take a look at the IL using ildasm.
Perhaps just because it is not explicitly created, it doesn't mean
that it's conceptually not there. Any basic value data type would be
foolish to have a constructor when all you need to do is shove zero(s)
into memory address(es).
So, you are saying there is no default constructor for structs, not
even conceptually? Then why does C# refuse the attempt to create a
struct constructor with no parameters? If there's no default
constructor, there should be no issue doing so. I think the reason
why is that one is implied, even thought it doesn't actually exist
explicitly in the byte code.
I think it is perhaps pedantic to state there is no constructor if
there really is one conceptually, but just not explicitly in the byte
code. But, I could be wrong. I don't know enough to know for sure.
I don't know what conceptual designs the byte code hides, if any.
Zytan
No, it's bad. Because I have a struct that contains only private data
members, as Jon Skeet wondefully pointed out is a good thing to do.
Therefore, I can only initialize those private members via constructor
(or declaration assignment -- I am not sure of the terminology of
that). Thus, if the default constructor does not disappear once I
create my own struct constructor, the caller can create a struct still
using the default constructor, setting all private / readonly fields
to 0, and they can never be changed. This is unfortunate for any
struct that has manually created constructors / properties that so
validity checking on the parameters.
What else do you want? structs are stored on the stack (or inlined with a heap allocated
object instance), that means if the fields are not set to their default value, that they
will contain the trash that's still in the stack.
Willy, you are missing my point.
Yes, junk would exist if no constructor is called. But, if I force
any use of a struct to use my constructor, then the values will be
what the constructor forces them to be. This is even better than
having them zeroed out. Imagine only having proper values. Zerod
values are better than junk values. Proper values are even better
than zeroed values.
if S wouldn't be set to 0, SomeObject could contain an address, left on the stack from a
previous call frame possibly containing a valid pointer or even a valid object reference,
but not a reference of SomeObject type, use your imaginatio and think what could happen in
such case....
I know all about it, Willy. I think it's great that languages
determine when variables are used before they are initialized, and C++
(at run time) and C# (at compile time, even better) are two such
languages. The above scenario, should never occur, even if variables
are not zeroed out. But, yes, zeroing them out adds an extra layer of
protection, I agree.
(Although, for structs that have NO manually created constructors, I
agree that the default constructor that sets all fields to 0 is a good
thing.)
No, its a perfect thing for all.
No, it's not perfect for all. How can you claim that? For my struct,
it should never, ever have zeros in it. Ever. Zeros are just not
proper values. Either the struct doesn't exist, or it exists with
specific values passed into its constructor. There is never a time
that it ever makes sense to have zeroes in it. Thus, if I can force
my constructor to be invoked every single time the struct is used,
then in all cases in the program, the struct will only ever contain
real, proper values, and will never contain imporper zero values.
To make such a claim "something is perfect for all" implies you've
thought of infinite possible cases. It's an impossible claim to make,
and can be disproven with a single case. I thought I had explained
that case prior to this post. I hope the above explains it
adequately.
I am dumbfounded as to your defensive behaviour. Did it arrive from
my claim that you were wrong that structs don't have a constructor?
All I am trying to do is find the truth by discussion. If I'm wrong,
I don't care, as long as I find the truth. My being wrong on one
thing doesn't make me automatically wrong on another.
If you don't want the struct to be initialized with default
values, make sure they are initialized correctly and handle the error cases.
But that means I must manually do what the compiler could handle for
me. I think the arrival of strict type checking showed why it is best
that the compiler handle as much as it can, since humans are prone to
error.
Zytan
"Zytan" <zy**********@yahoo.comwrote in message
news:11**********************@c51g2000cwc.googlegr oups.com...
Yes, junk would exist if no constructor is called. But, if I force
any use of a struct to use my constructor, then the values will be
what the constructor forces them to be. This is even better than
having them zeroed out. Imagine only having proper values. Zerod
values are better than junk values. Proper values are even better
than zeroed values.
It comes down to this: There's a deeply rooted assumption in the CLR that:
1. value types can always be copied as memory images.
2. that storage for a value type can always be initialized by filling the
memory with zeros.
If you can't live with those constraints, use a reference class instead of a
struct.
-cd
On Mar 8, 5:03 pm, "Carl Daniel [VC++ MVP]"
<cpdaniel_remove_this_and_nos...@mvps.org.nospamwr ote:
"Zytan" <zytanlith...@yahoo.comwrote in message
news:11**********************@c51g2000cwc.googlegr oups.com...
Yes, junk would exist if no constructor is called. But, if I force
any use of a struct to use my constructor, then the values will be
what the constructor forces them to be. This is even better than
having them zeroed out. Imagine only having proper values. Zerod
values are better than junk values. Proper values are even better
than zeroed values.
It comes down to this: There's a deeply rooted assumption in the CLR that:
1. value types can always be copied as memory images.
2. that storage for a value type can always be initialized by filling the
memory with zeros.
Ah. Finally. I was going to point that out.
Willy is right: in effect there _is no default constructor_. It was
omitted for value types for efficiency reasons. When you say:
public class Foo
{
private int x;
private float y;
private MyStruct z;
}
what happens is that all of the private field space for Foo is filled
with zeroes. The three fields aren't constructed individually. Then
Foo's constructor is run. If Foo's constructor forgets to initialize z
is some meaningful way, then it is left as it was: filled with zeroes.
All references it may contain are null, all integers are zero, all
booleans are false.
There is no default constructor, neither implied nor explicit. That is
to say, there is no piece of code emitted with the express job of
initializing MyStruct z, just some code that runs to generally
initialize the memory where Foo's state will go. This was, I believe
to make it cheap to create value types: there is never a need to call
implicit constructors: just a need to call explicit constructors if
you should invoke them in your code.
So what do you do in your MyStruct to handle this? One of two things:
1) Have MyStruct explicitly check for an un-constructed state and flag
it as illegal, usually by throwing an exception on property access /
method calls that can't be done before the struct is constructed
explicitly. I tend to avoid this because it just causes a mess at run-
time.
2) Give all-zeroes an interpretation. Decide what it means, and handle
that situtation. For example, in my Measure struct, all zeroes (and
nulls) means a scalar zero measurement (zero with no unit of measure
attached).
Structs are supposed to be very small and very simple. If your struct
starts to grow to be large and/or complicated then IMHO it's time to
re-evaluate the design.
Hi,
Why are you making this thing a struct anyway?
Why not make it a class?
"Zytan" <zy**********@yahoo.comwrote in message
news:11**********************@c51g2000cwc.googlegr oups.com...
No, it's bad. Because I have a struct that contains only private data
members, as Jon Skeet wondefully pointed out is a good thing to do.
Therefore, I can only initialize those private members via constructor
(or declaration assignment -- I am not sure of the terminology of
that). Thus, if the default constructor does not disappear once I
create my own struct constructor, the caller can create a struct still
using the default constructor, setting all private / readonly fields
to 0, and they can never be changed. This is unfortunate for any
struct that has manually created constructors / properties that so
validity checking on the parameters.
What else do you want? structs are stored on the stack (or inlined with a heap allocated object instance), that means if the fields are not set to their default value, that they will contain the trash that's still in the stack.
Willy, you are missing my point.
Yes, junk would exist if no constructor is called. But, if I force
any use of a struct to use my constructor, then the values will be
what the constructor forces them to be. This is even better than
having them zeroed out. Imagine only having proper values. Zerod
values are better than junk values. Proper values are even better
than zeroed values.
>if S wouldn't be set to 0, SomeObject could contain an address, left on the stack from a previous call frame possibly containing a valid pointer or even a valid object reference, but not a reference of SomeObject type, use your imaginatio and think what could happen in such case....
I know all about it, Willy. I think it's great that languages
determine when variables are used before they are initialized, and C++
(at run time) and C# (at compile time, even better) are two such
languages. The above scenario, should never occur, even if variables
are not zeroed out. But, yes, zeroing them out adds an extra layer of
protection, I agree.
(Although, for structs that have NO manually created constructors, I
agree that the default constructor that sets all fields to 0 is a good
thing.)
No, its a perfect thing for all.
No, it's not perfect for all. How can you claim that? For my struct,
it should never, ever have zeros in it. Ever. Zeros are just not
proper values. Either the struct doesn't exist, or it exists with
specific values passed into its constructor. There is never a time
that it ever makes sense to have zeroes in it. Thus, if I can force
my constructor to be invoked every single time the struct is used,
then in all cases in the program, the struct will only ever contain
real, proper values, and will never contain imporper zero values.
To make such a claim "something is perfect for all" implies you've
thought of infinite possible cases. It's an impossible claim to make,
and can be disproven with a single case. I thought I had explained
that case prior to this post. I hope the above explains it
adequately.
I am dumbfounded as to your defensive behaviour. Did it arrive from
my claim that you were wrong that structs don't have a constructor?
All I am trying to do is find the truth by discussion. If I'm wrong,
I don't care, as long as I find the truth. My being wrong on one
thing doesn't make me automatically wrong on another.
>If you don't want the struct to be initialized with default values, make sure they are initialized correctly and handle the error cases.
But that means I must manually do what the compiler could handle for
me. I think the arrival of strict type checking showed why it is best
that the compiler handle as much as it can, since humans are prone to
error.
Zytan
"Zytan" <zy**********@yahoo.comwrote in message
news:11**********************@8g2000cwh.googlegrou ps.com...
>Not sure what you mean here with default constructor, there is no such thing as a "default" constructor for structs.
>http://msdn2.microsoft.com/en-us/lib...ft(vs.80).aspx Ever heard of mistakes in MSDN?
Yes. Why the attitude? It's ok to be called on something you believe
is right.
This is not about attitude this is about reality, many things in MSDN are "wrong or "badly
worded", you can't and should never expect such huge piece of documentatin to be perfect.
It's up to the reader to correctly interpret what's been written, or to ask MSFT to correct
what's wrong.
I believe MSDN is correct this time because of further evidence
explained below.
"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."
>If you don't supply a constructor, the struct will get initialized by the runtime, such that all its fields have their default value, that is, the memory space (f.i on the stack) taken by the struct is set to 0.
Yes, by the default constructor.
No there is no *explicit* .ctor created by the compiler for a value type as it's the case for a class, take a look at the IL using ildasm.
Perhaps just because it is not explicitly created, it doesn't mean
that it's conceptually not there. Any basic value data type would be
foolish to have a constructor when all you need to do is shove zero(s)
into memory address(es).
No, it's not there, the fact that the memory is initialized with zero values, doesn't make
it a constructor.
The CLR goes to great lengths to assure that all memory allocated for the "object" on the GC
heap, or, a "value" on the Stack, is initialized with zero's before any explicit or compiler
generated constructor runs for the type.
Reference types (depending on their location on the GC heap) are stored on:
1) zero'd out memory pages, or
2) explicit zero'd out memory locations , no surprises here, this is all taken care of
by the CLR's memory allocator.
The stack locations that hold a value type will get:
1) properly aligned, depending on the platform requirements, and,
2) properly initialized at 0, *before* usage, that is, before a (possible) user defined
constructor runs.
Here, this initialization is taken care of by the JIT, who produces the fasted code possible
on the platform (xmm/sse).
Alll this is done before an *possible* constructor runs, it's even not part of the actual
"constrution".
Willy.
On 8 Mar 2007 15:29:44 -0800, "Zytan" <zy**********@yahoo.comwrote:
>Declare your own default constructor private:
private MyStruct() { }
http://msdn2.microsoft.com/en-us/lib...ft(vs.80).aspx "Compiler Error CS0568 Error Message Structs cannot contain explicit parameterless constructors 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."
>Because you have declared your own default constructor the compiler will not create one. Because you have declared it private no-one except you can ever call it. This makes your struct impossible to default construct, which will limit its use in some situations.
Yes, that thought works in C++ to prevent instantiation (to create 'static' classes that C++ does not support), and I thought maybe I could do it in C#, as you've thought, as well, but it doesn't work.
Zytan
Sorry about my mistake, I did indeed have my C++ hat on.
You could use a class as others have suggested. If you still want to
use a struct then add a bool field validConstructor. This will
default initialise to false, and can be set to true in your explicit
constructors. Check it at the start of those methods which cannot
handle zero values for all fields.
rossum
Sorry about my mistake, I did indeed have my C++ hat on.
Hey, no problem. I thought the same thing.
You could use a class as others have suggested. If you still want to
use a struct then add a bool field validConstructor. This will
default initialise to false, and can be set to true in your explicit
constructors. Check it at the start of those methods which cannot
handle zero values for all fields.
Yes, these are valid solutions. Thanks. I don't think my issue is
large enough to warrant any of these things. I am more just curious
as to why I can't remove the default zeroing out.
Zytan
Ever heard of mistakes in MSDN?
>
Yes. Why the attitude? It's ok to be called on something you believe
is right.
This is not about attitude this is about reality, many things in MSDN are "wrong or "badly
worded", you can't and should never expect such huge piece of documentatin to be perfect.
It's up to the reader to correctly interpret what's been written, or to ask MSFT to correct
what's wrong.
Answering a question with a snappy question is attitude. I don't
expect MSDN to be completely correct. MSDN is giving strong evidence
that it is true, so I believe it just may be true. When C# refuses to
allow me to make a constructor with 0 parameters, and MSDN tells me
explicitly that the reason I cannot do this is because a default
constructor already exists, then, yes, I am going to believe it. The
evidence supports this.
No, it's not there, the fact that the memory is initialized with zero values, doesn't make
it a constructor.
The CLR goes to great lengths to assure that all memory allocated for the "object" on the GC
heap, or, a "value" on the Stack, is initialized with zero's before any explicit or compiler
generated constructor runs for the type.
Reference types (depending on their location on the GC heap) are stored on:
1) zero'd out memory pages, or
2) explicit zero'd out memory locations , no surprises here, this is all taken care of
by the CLR's memory allocator.
The stack locations that hold a value type will get:
1) properly aligned, depending on the platform requirements, and,
2) properly initialized at 0, *before* usage, that is, before a (possible) user defined
constructor runs.
Here, this initialization is taken care of by the JIT, who produces the fasted code possible
on the platform (xmm/sse).
Alll this is done before an *possible* constructor runs, it's even not part of the actual
"constrution".
Ok, thanks for the in depth explanation. Things are always zeroed out
before a constructor is called. I get it. In fact, I think it's
great.
But, this doesn't prove that there is no default constructor for
structs. If the default cosntructor for structs is just to zero
things out, then it doesn't need to exist, and therefore doesn't have
to exist in the final byte code. The fact that everything is zeroed
out is one of the reasons such a default constructor needn't actually
exist, since it'd just do the same work again.
Again, I will ask: Why does C# disallow a parameterless constructor?
MSDN says it is because a default parameterless constructor exists.
If MSDN is wrong, then shouldn't the creation of a parameterless
constructor be allowed?
Zytan
It comes down to this: There's a deeply rooted assumption in the CLR that:
>
1. value types can always be copied as memory images.
2. that storage for a value type can always be initialized by filling the
memory with zeros.
If you can't live with those constraints, use a reference class instead of a
struct.
Ok, I understand. And I've always been happy that things are zeroed
out. Yet, it would be better if I could force my own constructor, but
structs are value types, and that breaks the CLR assumption. I get
it. It was just a question, and I know the answer now. I'll use a
class if that forced construction is that important to me.
Thanks,
Zytan
Willy is right: in effect there _is no default constructor_. It was
omitted for value types for efficiency reasons.
Ok, I know that no constructor is actually called, and yes, I totally
agree it is worth while for efficiency reasons. Imagine calling a
constructor for every int!
There is no default constructor, neither implied nor explicit. That is
to say, there is no piece of code emitted with the express job of
initializing MyStruct z, just some code that runs to generally
initialize the memory where Foo's state will go. This was, I believe
to make it cheap to create value types: there is never a need to call
implicit constructors: just a need to call explicit constructors if
you should invoke them in your code.
Yes, and again, I agree. It makes it quick.
But, you are just saying no code is run to initialize the value types
(which makes sense since it'd be slow). This doesn't prove that
conceptually there is no default cosntructor. Why doesn't C# allow me
to make a parameterless constructor if there is no default
constructor? I can see no reason why C# would disallow a
parameterless constructor *unless* one already exists, which is what
MSDN says, which is why I believe it (although, I know it is wrong a
lot of the time).
So far, the only evidence either way supports that (at least
conceptually) a default parameterless constructor exists for struct.
So what do you do in your MyStruct to handle this? One of two things:
1) Have MyStruct explicitly check for an un-constructed state and flag
it as illegal, usually by throwing an exception on property access /
method calls that can't be done before the struct is constructed
explicitly. I tend to avoid this because it just causes a mess at run-
time.
I've done this for C++ to allow static classes which it doesn't
support. I dislike it, but there was no better choice.
2) Give all-zeroes an interpretation. Decide what it means, and handle
that situtation. For example, in my Measure struct, all zeroes (and
nulls) means a scalar zero measurement (zero with no unit of measure
attached).
Yes. It is quite convenient that every data type means something
decent when its bytes are zeroed out, isn't it?
Structs are supposed to be very small and very simple. If your struct
starts to grow to be large and/or complicated then IMHO it's time to
re-evaluate the design.
My struct is quite simple. A zeroed out struct means nothing,
unfortunately, but it's not complicated enough to require a class. If
this becomes an issue, I'll use a class.
Thanks for the explanation, and plausible options!
Zytan
Hi,
>
Why are you making this thing a struct anyway?
Why not make it a class?
Hi,
Bill, it's just a few strings and ints that are related. And I want
to pass this data all at the same time (rather use many parameters),
so I put them together in a struct. Then, Jon Skeet said structs are
better off with private data members, so I made them readonly
(although he prefers properties, since they allow for future
modification, and I agree, but my struct is too simple for that). So,
then I needed a constructor to set the values.
Then I realized the values could be set by accident to all 0's (and
can never be fixed) if the default constructor is applied. I just
really hate it when languages do things implicitly like this. Reminds
me of C++'s desire to make copy constructors, default constructors,
etc., when you don't want them. I feel like saying, "stop helping me,
because it's not helping." So, now, everything's perfect except for
this C# implied default constructor that zeros everything out, which
could be invoked by accident. It'd be nice if I could override it.
It'd be best if it didn't exist (once I made my own constructor, that
is).
So, it's funny how a little struct can be moved into a position,
incrementally, by doing The Right Thing each step, to where people are
dumbfounded why it shouldn't be a class. In that account, every
struct should be a class. :) And yes, if it was more complicated than
this, I would use a class. The journey has been fun!
Cheers,
Zytan
Zytan wrote:
Yes, junk would exist if no constructor is called. But, if I force
any use of a struct to use my constructor, then the values will be
what the constructor forces them to be. This is even better than
having them zeroed out. Imagine only having proper values. Zerod
values are better than junk values. Proper values are even better
than zeroed values.
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).
No, it's not perfect for all. How can you claim that? For my struct,
it should never, ever have zeros in it. Ever. Zeros are just not
proper values.
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.
If it's still too much of a problem, don't use structs. Use classes.
I am dumbfounded as to your defensive behaviour.
Take a chill pill, man!
-- Barry
-- http://barrkel.blogspot.com/
Zytan wrote:
Bill, it's just a few strings and ints that are related. And I want
to pass this data all at the same time (rather use many parameters),
so I put them together in a struct.
Structs are more suited to values where copies need to be distinct, i.e.
the type modeled needs to have value semantics in the same ways as e.g.
a Complex type would. In other words, structs are useful to avoid the
aliasing issues of classes.
Also, structs work best if they are read-only, otherwise you get funny
issues with e.g. { List<Pointlist; /* ... */ list[i].Foo = 42; } won't
actually modify an item in the list, but a temporary value that gets
discarded.
Performance benefits, if there are any (you need to measure), need to be
more dramatic in order to justify the decision to use structs rather
than classes, IMHO.
Then, Jon Skeet said structs are
better off with private data members, so I made them readonly
(although he prefers properties, since they allow for future
modification, and I agree, but my struct is too simple for that).
Nonsense - no struct is too simple to have private fields with public
properties rather than public fields.
Trivial property accessors get inlined. There's no good reason to have
public fields, pretty much ever.
-- Barry
-- http://barrkel.blogspot.com/
"Zytan" <zy**********@yahoo.comwrote in message
news:11**********************@c51g2000cwc.googlegr oups.com...
>Ever heard of mistakes in MSDN?
Yes. Why the attitude? It's ok to be called on something you believe
is right.
This is not about attitude this is about reality, many things in MSDN are "wrong or "badly worded", you can't and should never expect such huge piece of documentatin to be perfect. It's up to the reader to correctly interpret what's been written, or to ask MSFT to correct what's wrong.
Answering a question with a snappy question is attitude. I don't
expect MSDN to be completely correct. MSDN is giving strong evidence
that it is true, so I believe it just may be true. When C# refuses to
allow me to make a constructor with 0 parameters, and MSDN tells me
explicitly that the reason I cannot do this is because a default
constructor already exists, then, yes, I am going to believe it. The
evidence supports this.
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.
>No, it's not there, the fact that the memory is initialized with zero values, doesn't make it a constructor. The CLR goes to great lengths to assure that all memory allocated for the "object" on the GC heap, or, a "value" on the Stack, is initialized with zero's before any explicit or compiler generated constructor runs for the type. Reference types (depending on their location on the GC heap) are stored on: 1) zero'd out memory pages, or 2) explicit zero'd out memory locations , no surprises here, this is all taken care of by the CLR's memory allocator. The stack locations that hold a value type will get: 1) properly aligned, depending on the platform requirements, and, 2) properly initialized at 0, *before* usage, that is, before a (possible) user defined constructor runs. Here, this initialization is taken care of by the JIT, who produces the fasted code possible on the platform (xmm/sse). Alll this is done before an *possible* constructor runs, it's even not part of the actual "constrution".
Ok, thanks for the in depth explanation. Things are always zeroed out
before a constructor is called. I get it. In fact, I think it's
great.
But, this doesn't prove that there is no default constructor for
structs. If the default cosntructor for structs is just to zero
things out, then it doesn't need to exist,
True, there is no "default constructor" for value types.
and therefore doesn't have
to exist in the final byte code. The fact that everything is zeroed
out is one of the reasons such a default constructor needn't actually
exist, since it'd just do the same work again.
True, that's why there is no such "default constructor", why do you keep on insisting on
this?
>
Again, I will ask: Why does C# disallow a parameterless constructor?
A parameter-less user defined constructor *is* a default constructor! And value types DO NOT
SUPPORT default constructors!
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.
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*.
And that's exactly what the C# compiler is generating, depending on whether the struct
(value type) has a user defined (obviously one with parameters)constructor or not.
MSDN says it is because a default parameterless constructor exists.
If MSDN is wrong,
Well, It is!
then shouldn't the creation of a parameterless
constructor be allowed?
Again, because parameter-less constructors are "default constructors" ( or "user defined
special member function") and these are not allowed in value types!
Willy.
[1] From ECMA-372 C++/CLI Language Specification.
12.2.1 Value classes
[Note: A value class is a data structure that can contain fields, function members, and
nested types. Unlike
other class types, value classes do not support user-defined destructors, finalizers,
default constructors, copy
constructors, or copy assignment operators. Value classes are designed to allow the CLI
execution engine to
efficiently copy value class objects.
[2]From ECMA-335 ch. 8.9.7
5. Unlike object types, instances of value types do not require a constructor to be called
when an
instance is created. Instead, the verification rules require that verifiable code initialize
instances
to zero (null for object fields).
[3] From ECMA-335 12.1.6.2.1 Initializing instances of value types
There are three options for initializing the home of a value type instance. You can zero it
by loading the address
of the home (see Table 8: Address and Type of Home Locations) and using the initobj
instruction (for local
variables this is also accomplished by setting the localsinit bit in the method's header).
You can call a userdefined
constructor by loading the address of the home (see Table 8: Address and Type of Home
Locations)
and then calling the constructor directly. Or you can copy an existing instance into the
home, as described
in §12.1.6.2.2.
"Zytan" <zy**********@yahoo.comwrote in message
news:11**********************@t69g2000cwt.googlegr oups.com...
>Sorry about my mistake, I did indeed have my C++ hat on.
Hey, no problem. I thought the same thing.
>You could use a class as others have suggested. If you still want to use a struct then add a bool field validConstructor. This will default initialise to false, and can be set to true in your explicit constructors. Check it at the start of those methods which cannot handle zero values for all fields.
Yes, these are valid solutions. Thanks. I don't think my issue is
large enough to warrant any of these things. I am more just curious
as to why I can't remove the default zeroing out.
Actually, I think the zeroing is done en masse, whenever the gc compacts the
heap, the newly freed memory is zeroed. Then, a new structure instance can
be created by just reserving memory and no need to call any constructor at
all.
>
Zytan
Ben Voigt wrote:
Yes, these are valid solutions. Thanks. I don't think my issue is
large enough to warrant any of these things. I am more just curious
as to why I can't remove the default zeroing out.
Actually, I think the zeroing is done en masse, whenever the gc compacts the
heap, the newly freed memory is zeroed. Then, a new structure instance can
be created by just reserving memory and no need to call any constructor at
all.
Yes, for structs that are part of an array or other reference type.
However, many structs will be locals or parameters, for which zeroing
out theoretically takes extra time, if the JIT optimizer doesn't detect
the redundant zeroing.
-- Barry
-- http://barrkel.blogspot.com/
Zytan wrote:
Again, I will ask: Why does C# disallow a parameterless constructor?
MSDN says it is because a default parameterless constructor exists.
If MSDN is wrong, then shouldn't the creation of a parameterless
constructor be allowed?
A better reference for C# and .NET low-level behaviour are the ECMA
specs, see #334 and #335. They're freely downloadable specs from http://www.ecma-international.org/ .
-- Barry
-- http://barrkel.blogspot.com/
"Barry Kelly" <ba***********@gmail.comwrote in message
news:qu********************************@4ax.com...
Ben Voigt wrote:
Yes, these are valid solutions. Thanks. I don't think my issue is
large enough to warrant any of these things. I am more just curious
as to why I can't remove the default zeroing out.
Actually, I think the zeroing is done en masse, whenever the gc compacts the heap, the newly freed memory is zeroed. Then, a new structure instance can be created by just reserving memory and no need to call any constructor at all.
Yes, for structs that are part of an array or other reference type.
However, many structs will be locals or parameters, for which zeroing
out theoretically takes extra time, if the JIT optimizer doesn't detect
the redundant zeroing.
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.
>
-- Barry
-- http://barrkel.blogspot.com/
Ben Voigt wrote:
>
"Barry Kelly" <ba***********@gmail.comwrote in message
news:qu********************************@4ax.com...
Ben Voigt wrote:
Yes, these are valid solutions. Thanks. I don't think my issue is
large enough to warrant any of these things. I am more just curious
as to why I can't remove the default zeroing out.
Actually, I think the zeroing is done en masse, whenever the gc compacts
the
heap, the newly freed memory is zeroed. Then, a new structure instance
can
be created by just reserving memory and no need to call any constructor
at
all.
Yes, for structs that are part of an array or other reference type.
However, many structs will be locals or parameters, for which zeroing
out theoretically takes extra time, if the JIT optimizer doesn't detect
the redundant zeroing.
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.
Yes, I fully agree with you. I was just broadening the point to include
locals, rather than just having the GC responsible.
-- Barry
-- http://barrkel.blogspot.com/
Zytan <zy**********@yahoo.comwrote:
Why are you making this thing a struct anyway?
Why not make it a class?
Bill, it's just a few strings and ints that are related. And I want
to pass this data all at the same time (rather use many parameters),
so I put them together in a struct.
None of that has anything to do with whether it should be a struct or a
class. You should only ask yourself whether you want value type
semantics or reference type semantics.
Personally, I can only remember about 2 structs I've ever written. I
almost *always* use classes.
--
Jon Skeet - <sk***@pobox.com> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Willy Denoyette [MVP] <wi*************@telenet.bewrote:
This is not about attitude this is about reality, many things in MSDN
are "wrong or "badly worded", you can't and should never expect such
huge piece of documentatin to be perfect. It's up to the reader to
correctly interpret what's been written, or to ask MSFT to correct
what's wrong.
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.
This isn't the only place that C# terminology and CLR/CLI terminology
clash a bit.
--
Jon Skeet - <sk***@pobox.com> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Willy Denoyette [MVP] <wi*************@telenet.bewrote:
<snip>
Again, I will ask: Why does C# disallow a parameterless constructor?
A parameter-less user defined constructor *is* a default 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.
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)
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.
--
Jon Skeet - <sk***@pobox.com> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
On Mar 9, 10:11 am, "Zytan" <zytanlith...@yahoo.comwrote:
Hi,
Why are you making this thing a struct anyway?
Why not make it a class?
Hi,
Bill, it's just a few strings and ints that are related. And I want
to pass this data all at the same time (rather use many parameters),
so I put them together in a struct.
I would use a simple class for this. Even make all fields public if
you want to just use it as a container. Remember: "struct" in C# has
implications far beyond what it has in, say, C++. In C# it's a
specialized tool, rather than a nuance on "class".
Use a class in this case. You'll find that it works out better.
"Jon Skeet [C# MVP]" <sk***@pobox.comwrote in message
news:MP************************@msnews.microsoft.c om...
Willy Denoyette [MVP] <wi*************@telenet.bewrote:
<snip>
Again, I will ask: Why does C# disallow a parameterless constructor?
A parameter-less user defined constructor *is* a default 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.
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 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)
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.
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?
All what the C# compiler does in this case is:
- When a local holds a value type, then the value is initialized by means of the .locals
init, and this at method entry.
Now, C# is a bit paranoic about this, it also emits an "initobj" at the point of
declaration (after moving the local address on the evaluation stack), as a result of the (C#
compiler enforced) new T(); call.
Note that the latter is optimized away by the JIT.
- When a field holds a value type, then the compiler emits an "initobj" (after moving...).
Only when there is a "user defined parameterized constructor" call, then will the compiler
emit "newobj instance void .ctor(arg, ..);" in IL.
In this case the JIT compiler will not optimize away the "locals int" action, that means
that even now the local holding the value type will still get initialized to 0. As I said
previously this is no big deal, the locals init is bloody fast (unless you don't get what
structs are made for in .NET ;-)).
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.
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.
Willy.
"Jon Skeet [C# MVP]" <sk***@pobox.comwrote in message
news:MP************************@msnews.microsoft.c om...
Willy Denoyette [MVP] <wi*************@telenet.bewrote:
>This is not about attitude this is about reality, many things in MSDN are "wrong or "badly worded", you can't and should never expect such huge piece of documentatin to be perfect. It's up to the reader to correctly interpret what's been written, or to ask MSFT to correct what's wrong.
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.
This isn't the only place that C# terminology and CLR/CLI terminology
clash a bit.
I would agree if C# was the only language on the CLR, but it isn't true, heck, some people
even think that C# is .NET.
And this is exactly what the ECMA-334 reflects, that document was written at the time C# was
the only language on the CLR submitted to ECMA, Now that we have three ECMA standard
language docs available(C# and C++/CLI and Eiffel), the inconsistencies become apparent,
none of them are perfect, but ECMA-334 shows his age and history.
Willy.
Willy Denoyette [MVP] <wi*************@telenet.bewrote:
I would agree if C# was the only language on the CLR, but it isn't
true, heck, some people even think that C# is .NET.
On the other hand, the C# language doesn't *have* to run on the CLR.
That's the only implementation I'm aware of, but it's not guaranteed.
And this is exactly what the ECMA-334 reflects, that document was
written at the time C# was the only language on the CLR submitted to
ECMA, Now that we have three ECMA standard language docs available(C#
and C++/CLI and Eiffel), the inconsistencies become apparent, none of
them are perfect, but ECMA-334 shows his age and history.
Indeed - but it's consistent with itself, so as long as one is aware
that what is true in C# terminology isn't necessarily true in CLR
terminology and vice versa, I think it's okay to say that from the C#
point of view, value types have default parameterless constructors.
--
Jon Skeet - <sk***@pobox.com> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
"Jon Skeet [C# MVP]" <sk***@pobox.comwrote in message
news:MP************************@msnews.microsoft.c om...
Willy Denoyette [MVP] <wi*************@telenet.bewrote:
>I would agree if C# was the only language on the CLR, but it isn't true, heck, some people even think that C# is .NET.
On the other hand, the C# language doesn't *have* to run on the CLR.
That's the only implementation I'm aware of, but it's not guaranteed.
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.
>And this is exactly what the ECMA-334 reflects, that document was written at the time C# was the only language on the CLR submitted to ECMA, Now that we have three ECMA standard language docs available(C# and C++/CLI and Eiffel), the inconsistencies become apparent, none of them are perfect, but ECMA-334 shows his age and history.
Indeed - but it's consistent with itself, so as long as one is aware
that what is true in C# terminology isn't necessarily true in CLR
terminology and vice versa, I think it's okay to say that from the C#
point of view, value types have default parameterless constructors.
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.
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.
Note, however, that an instance of a value type, can have a parameterless constructor. 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".
[1] a somewhat redundant "initobj", as the variable (local or embedded) holding the value is
already initialized at zero, because of the "initlocals" bit (emitted by the same
compiler!), or in case of embedded values, because of the GC/memory allocator action (an
implementation detail).
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.
Willy.
Yes, these are valid solutions. Thanks. I don't think my issue is
large enough to warrant any of these things. I am more just curious
as to why I can't remove the default zeroing out.
Actually, I think the zeroing is done en masse, whenever the gc compacts the
heap, the newly freed memory is zeroed. Then, a new structure instance can
be created by just reserving memory and no need to call any constructor at
all.
You're right, and I knew that.
I meant to say: "I am more just curious as to why I can't disallow
anyone from creating a struct without calling my own constructor."
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.
Ah, now we are getting to the truth. Thanks, Barry. This makes
sense. Do you know from which blog you are quoting?
Zytan
Thanks, Barry.
Sorry, I meant Ben!
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
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#).
But, this doesn't prove that there is no default constructor for
structs. If the default cosntructor for structs is just to zero
things out, then it doesn't need to exist,
True, there is no "default constructor" for value types.
and therefore doesn't have
It's a reason why it can be optimized out.
to exist in the final byte code. The fact that everything is zeroed
out is one of the reasons such a default constructor needn't actually
exist, since it'd just do the same work again.
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.
Again, I will ask: Why does C# disallow a parameterless constructor?
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
Again, I will ask: Why does C# disallow a parameterless constructor?
>
A parameter-less user defined constructor *is* a default 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
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.
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)
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
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
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
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.
No, it's not perfect for all. How can you claim that? For my struct,
it should never, ever have zeros in it. Ever. Zeros are just not
proper values.
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.
I am dumbfounded as to your defensive behaviour.
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
"Zytan" <zy**********@yahoo.comwrote in message
news:11**********************@s48g2000cws.googlegr oups.com...
>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.
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 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" .
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.
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.
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'.
Just because something it optimized out, it
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
Willy Denoyette [MVP] <wi*************@telenet.bewrote:
On the other hand, the C# language doesn't *have* to run on the CLR.
That's the only implementation I'm aware of, but it's not guaranteed.
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.
And this is exactly what the ECMA-334 reflects, that document was
written at the time C# was the only language on the CLR submitted to
ECMA, Now that we have three ECMA standard language docs available(C#
and C++/CLI and Eiffel), the inconsistencies become apparent, none of
them are perfect, but ECMA-334 shows his age and history.
Indeed - but it's consistent with itself, so as long as one is aware
that what is true in C# terminology isn't necessarily true in CLR
terminology and vice versa, I think it's okay to say that from the C#
point of view, value types have default parameterless constructors.
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.
--
Jon Skeet - <sk***@pobox.com> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Peter van der Goes |
last post by:
When a struct is created in C# and a parameterized constructor defined, the
IntelliSense editor shows only the syntax for the parameterized...
|
by: Karl M |
last post by:
Hi everyone,
I just notice some strange behaviors on the MS C++ compiler regarding struct
default constructor, see the example bellow:
struct...
|
by: Kemmylinns12 |
last post by:
Blockchain technology has emerged as a transformative force in the business world, offering unprecedented opportunities for innovation and...
|
by: Naresh1 |
last post by:
What is WebLogic Admin Training?
WebLogic Admin Training is a specialized program designed to equip individuals with the skills and knowledge...
|
by: jalbright99669 |
last post by:
Am having a bit of a time with URL Rewrite. I need to incorporate http to https redirect with a reverse proxy. I have the URL Rewrite rules made...
|
by: Matthew3360 |
last post by:
Hi there. I have been struggling to find out how to use a variable as my location in my header redirect function.
Here is my code.
...
|
by: Matthew3360 |
last post by:
Hi, I have a python app that i want to be able to get variables from a php page on my webserver. My python app is on my computer. How would I make it...
|
by: Matthew3360 |
last post by:
Hi,
I have been trying to connect to a local host using php curl. But I am finding it hard to do this. I am doing the curl get request from my web...
|
by: Oralloy |
last post by:
Hello Folks,
I am trying to hook up a CPU which I designed using SystemC to I/O pins on an FPGA.
My problem (spelled failure) is with the...
|
by: BLUEPANDA |
last post by:
At BluePanda Dev, we're passionate about building high-quality software and sharing our knowledge with the community. That's why we've created a SaaS...
|
by: Rahul1995seven |
last post by:
Introduction:
In the realm of programming languages, Python has emerged as a powerhouse. With its simplicity, versatility, and robustness, Python...
| |