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

Can't assign value to structure in array?

P: n/a
I have created a structure with five fields. I then create an array of this
type of structure and place the structure into an array element. Say index
one. I want to assign a value to field3 of the structure inside the array.
When I try this, an error about late assignment appears. Is it possible to
assign a value to a structure field that is in an array?

I'm currently getting around the problem by creating a new structure, assign
the structure fields using values in the arary...minus field 3, which gets a
value from somewhere else. I then place this structure into the array.

Thanks,
Brett
Nov 17 '05 #1
Share this Question
Share on Google+
26 Replies


P: n/a
Brett,

That's pretty much the way that you have to do it. It's the same
problem you would have if you were to return a structure from a property on
a class. Since a copy is returned, you have to store the copy, then
reassign it.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Brett" <no@spam.com> wrote in message
news:%2***************@TK2MSFTNGP15.phx.gbl...
I have created a structure with five fields. I then create an array of
this type of structure and place the structure into an array element. Say
index one. I want to assign a value to field3 of the structure inside the
array. When I try this, an error about late assignment appears. Is it
possible to assign a value to a structure field that is in an array?

I'm currently getting around the problem by creating a new structure,
assign the structure fields using values in the arary...minus field 3,
which gets a value from somewhere else. I then place this structure into
the array.

Thanks,
Brett

Nov 17 '05 #2

P: n/a
All structures should be immutable. If is it possible to change the
structure in any perceivable way, then chances are it will be used
incorrectly. For example, if you return the structure from a property, one
may think that changing the structure will change the class.

myClass.myStructProperty.myValue = 5;

this compiles as...

aStruct temp = myClass.myStructProperty;
temp.myValue = 5;
//throw away temp and its new value.


********

As for you specific problem, post the code.

--
Jonathan Allen
"Brett" <no@spam.com> wrote in message
news:%2***************@TK2MSFTNGP15.phx.gbl...
I have created a structure with five fields. I then create an array of
this type of structure and place the structure into an array element. Say
index one. I want to assign a value to field3 of the structure inside the
array. When I try this, an error about late assignment appears. Is it
possible to assign a value to a structure field that is in an array?

I'm currently getting around the problem by creating a new structure,
assign the structure fields using values in the arary...minus field 3,
which gets a value from somewhere else. I then place this structure into
the array.

Thanks,
Brett

Nov 17 '05 #3

P: n/a
Ok, you confirmed that is the way to do it but why?. Why exactly can't I
assign values to the structure fields that are in the array but can when
they aren't in the array?

If it were just a simple array element I could assign a value.
Thanks,
Brett
"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.com> wrote in
message news:ep****************@TK2MSFTNGP14.phx.gbl...
Brett,

That's pretty much the way that you have to do it. It's the same
problem you would have if you were to return a structure from a property
on a class. Since a copy is returned, you have to store the copy, then
reassign it.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Brett" <no@spam.com> wrote in message
news:%2***************@TK2MSFTNGP15.phx.gbl...
I have created a structure with five fields. I then create an array of
this type of structure and place the structure into an array element. Say
index one. I want to assign a value to field3 of the structure inside
the array. When I try this, an error about late assignment appears. Is it
possible to assign a value to a structure field that is in an array?

I'm currently getting around the problem by creating a new structure,
assign the structure fields using values in the arary...minus field 3,
which gets a value from somewhere else. I then place this structure into
the array.

Thanks,
Brett


Nov 17 '05 #4

P: n/a
Brett,

Here is the reason why. Say you have the following structure
declaration:

public struct MyStruct
{
public int MyInt;
}

Then you have this array:

// Create an array with three elements.
MyStruct[] structs = new MyStruct[3];

At that point, you have an array of three structures with MyInt values
of 0. Now when you do this:

// Assign MyInt on the first element of the array.
structs[0].MyInt = 2;

The statement structs[0] returns a copy of the element in the array, and
you end up setting the MyInt field on the copy, not the original.

Now, this should not give you a compiler error, but it's definitely not
behavior that you want. I am curious what the code is that is giving you
the error.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Brett" <no@spam.com> wrote in message
news:%2******************@TK2MSFTNGP15.phx.gbl...
Ok, you confirmed that is the way to do it but why?. Why exactly can't I
assign values to the structure fields that are in the array but can when
they aren't in the array?

If it were just a simple array element I could assign a value.
Thanks,
Brett
"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.com> wrote
in message news:ep****************@TK2MSFTNGP14.phx.gbl...
Brett,

That's pretty much the way that you have to do it. It's the same
problem you would have if you were to return a structure from a property
on a class. Since a copy is returned, you have to store the copy, then
reassign it.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Brett" <no@spam.com> wrote in message
news:%2***************@TK2MSFTNGP15.phx.gbl...
I have created a structure with five fields. I then create an array of
this type of structure and place the structure into an array element.
Say index one. I want to assign a value to field3 of the structure
inside the array. When I try this, an error about late assignment
appears. Is it possible to assign a value to a structure field that is
in an array?

I'm currently getting around the problem by creating a new structure,
assign the structure fields using values in the arary...minus field 3,
which gets a value from somewhere else. I then place this structure
into the array.

Thanks,
Brett



Nov 17 '05 #5

P: n/a
Here's the code. It's in VB.NET but you can see well what is going on. I'm
converting to C# but wanted to get past this first.

For x As Integer = 0 To ParsedMessage.Length - 1

'create space for new array element
ReDim Preserve imageMapInfoArr(x)

' copy into new structure
imageMapInfo.TickCount_ = ParsedMessage(x).TickCount_
imageMapInfo.Server_StatusCode = ParsedMessage(x).Server_StatusCode
imageMapInfo.URLDestination = ParsedMessage(x).URLDestination
imageMapInfo.ImageURLInSourceText = strImageMapImage
imageMapInfo.URLSourceType = "Image Map"
imageMapInfo.URLSource = ParsedMessage(x).URLSource
imageMapInfoArr(x) = imageMapInfo
Next

I can't do something like:
ParsedMessage(x).URLSourceType = "Image Map"

That's why I'm doing it like the above.

Thanks,
Brett

"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.com> wrote in
message news:u0*************@tk2msftngp13.phx.gbl...
Brett,

Here is the reason why. Say you have the following structure
declaration:

public struct MyStruct
{
public int MyInt;
}

Then you have this array:

// Create an array with three elements.
MyStruct[] structs = new MyStruct[3];

At that point, you have an array of three structures with MyInt values
of 0. Now when you do this:

// Assign MyInt on the first element of the array.
structs[0].MyInt = 2;

The statement structs[0] returns a copy of the element in the array,
and you end up setting the MyInt field on the copy, not the original.

Now, this should not give you a compiler error, but it's definitely not
behavior that you want. I am curious what the code is that is giving you
the error.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Brett" <no@spam.com> wrote in message
news:%2******************@TK2MSFTNGP15.phx.gbl...
Ok, you confirmed that is the way to do it but why?. Why exactly can't I
assign values to the structure fields that are in the array but can when
they aren't in the array?

If it were just a simple array element I could assign a value.
Thanks,
Brett
"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.com> wrote
in message news:ep****************@TK2MSFTNGP14.phx.gbl...
Brett,

That's pretty much the way that you have to do it. It's the same
problem you would have if you were to return a structure from a property
on a class. Since a copy is returned, you have to store the copy, then
reassign it.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Brett" <no@spam.com> wrote in message
news:%2***************@TK2MSFTNGP15.phx.gbl...
I have created a structure with five fields. I then create an array of
this type of structure and place the structure into an array element.
Say index one. I want to assign a value to field3 of the structure
inside the array. When I try this, an error about late assignment
appears. Is it possible to assign a value to a structure field that is
in an array?

I'm currently getting around the problem by creating a new structure,
assign the structure fields using values in the arary...minus field 3,
which gets a value from somewhere else. I then place this structure
into the array.

Thanks,
Brett



Nov 17 '05 #6

P: n/a
Nicholas Paldino [.NET/C# MVP] <mv*@spam.guard.caspershouse.com> wrote:
Here is the reason why. Say you have the following structure
declaration:

public struct MyStruct
{
public int MyInt;
}

Then you have this array:

// Create an array with three elements.
MyStruct[] structs = new MyStruct[3];

At that point, you have an array of three structures with MyInt values
of 0. Now when you do this:

// Assign MyInt on the first element of the array.
structs[0].MyInt = 2;

The statement structs[0] returns a copy of the element in the array, and
you end up setting the MyInt field on the copy, not the original.


That's not actually true. Try this, for example:

using System;
using System.Drawing;

class Test
{
static void Main()
{
Point[] p = new Point[50];
p[0].X=5;
Console.WriteLine (p[0]);
}
}

The result is:
{X=5,Y=0}

Arrays are treated as sets of variables, effectively - even the C#
language specification talks about them that way. Note that this is
very different from the behaviour you'd get if you were using an
indexer, or a property.

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

P: n/a
Brett <no@spam.com> wrote:
I have created a structure with five fields. I then create an array of this
type of structure and place the structure into an array element. Say index
one. I want to assign a value to field3 of the structure inside the array.
When I try this, an error about late assignment appears. Is it possible to
assign a value to a structure field that is in an array?


Could you post a short but complete program which demonstrates the
problem?

See http://www.pobox.com/~skeet/csharp/complete.html for details of
what I mean by that.

Being in an array shouldn't be a problem in itself. Here's an example
of what it sounds like you're doing:

using System;
using System.Drawing;

struct Foo
{
public int Field1;
public int Field2;

public override string ToString()
{
return string.Format("{0}/{1}", Field1, Field2);
}
}

class Test
{
static void Main()
{
Foo[] f = new Foo[10];
f[0].Field1=10;
f[1].Field2=5;

Console.WriteLine (f[0]);
Console.WriteLine (f[1]);
}
}

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

P: n/a
If the struct is small, you should post its code as well.
ReDim Preserve imageMapInfoArr(x)
Move this outside of the loop.

--
Jonathan Allen
"Brett" <no@spam.com> wrote in message
news:u$**************@TK2MSFTNGP09.phx.gbl... Here's the code. It's in VB.NET but you can see well what is going on.
I'm converting to C# but wanted to get past this first.

For x As Integer = 0 To ParsedMessage.Length - 1

'create space for new array element
ReDim Preserve imageMapInfoArr(x)

' copy into new structure
imageMapInfo.TickCount_ = ParsedMessage(x).TickCount_
imageMapInfo.Server_StatusCode = ParsedMessage(x).Server_StatusCode
imageMapInfo.URLDestination = ParsedMessage(x).URLDestination
imageMapInfo.ImageURLInSourceText = strImageMapImage
imageMapInfo.URLSourceType = "Image Map"
imageMapInfo.URLSource = ParsedMessage(x).URLSource
imageMapInfoArr(x) = imageMapInfo
Next

I can't do something like:
ParsedMessage(x).URLSourceType = "Image Map"

That's why I'm doing it like the above.

Thanks,
Brett

Nov 17 '05 #9

P: n/a
Note that it makes a big difference whether it is an array:

MyStruct arr = new MyStruct[15];

....or a collection:

ArrayList arr = new ArrayList();
arr.Add(new MyStruct());
....etc.

In the first case, as Jon pointed out, .NET stores the array of a
contiguous chunk of memory containing the values for all of the
structs. In the second case, the structs are boxed and references to
the structs are stored in the ArrayList.

In the first case you can do things like

arr[9].Property = 5;

and it works. In the second case, you can't, because the struct must be
boxed when it's put in the ArrayList, and unboxed when it's removed, so
you only ever get a copy back.

As Jonathan pointed out, structs should, in general, be immutable. To
change a value in a struct you should construct a new one using values
from the old one (except for the value you want to change). Creating
mutable structs is just asking for trouble. In fact, if you're creating
a mutable struct, it begs the question of why you made it a struct to
start with. Why isn't it a class?

Nov 17 '05 #10

P: n/a
That error message is a big red flag telling you that this should not be a
struct, but should be a class instead. There's very little reason to use
structs in .Net programming -- use them only when you need a new thing
that's treated and manipulated immutably.

"Brett" <no@spam.com> wrote in message
news:%2***************@TK2MSFTNGP15.phx.gbl...
I have created a structure with five fields. I then create an array of
this type of structure and place the structure into an array element. Say
index one. I want to assign a value to field3 of the structure inside the
array. When I try this, an error about late assignment appears. Is it
possible to assign a value to a structure field that is in an array?

I'm currently getting around the problem by creating a new structure,
assign the structure fields using values in the arary...minus field 3,
which gets a value from somewhere else. I then place this structure into
the array.

Thanks,
Brett

Nov 17 '05 #11

P: n/a
It is an arraylist and not an array so what you have said makes sense. Ok,
a couple have suggested this should possibly be a class. I still don't get
why people are saying the thing I'm doing is a red flag. I'm trying to
reassign values to structure fields within one element of an array. I know
the particular element and the fields of the structure within that element.
So it isn't as if there are other areas in the program that are also
accessing this structure in the same arraylist element.

My flow goes like this:
1. create new structure and assign values
2. put structure into arraylist position (i.e. position 2)
3. new conditions have created values that need to be assigned to certain
structure fields in position two of the arraylist
4. loop through arraylist and assign structure values to a database

My point is that the structure is access only three times. Two writes and
one read. This isn't complicated and I don't have to worry about
accidentally assigning a value to the structure while it is being read
somewhere else. That can't happen since the flow is procedural. I believe
that is the red flag some of you were thinking about.

Please elaborate on the above of where I may be wrong or have
misinterpreted.

Thanks,
Brett

"Bruce Wood" <br*******@canada.com> wrote in message
news:11**********************@g49g2000cwa.googlegr oups.com...
Note that it makes a big difference whether it is an array:

MyStruct arr = new MyStruct[15];

...or a collection:

ArrayList arr = new ArrayList();
arr.Add(new MyStruct());
...etc.

In the first case, as Jon pointed out, .NET stores the array of a
contiguous chunk of memory containing the values for all of the
structs. In the second case, the structs are boxed and references to
the structs are stored in the ArrayList.

In the first case you can do things like

arr[9].Property = 5;

and it works. In the second case, you can't, because the struct must be
boxed when it's put in the ArrayList, and unboxed when it's removed, so
you only ever get a copy back.

As Jonathan pointed out, structs should, in general, be immutable. To
change a value in a struct you should construct a new one using values
from the old one (except for the value you want to change). Creating
mutable structs is just asking for trouble. In fact, if you're creating
a mutable struct, it begs the question of why you made it a struct to
start with. Why isn't it a class?

Nov 17 '05 #12

P: n/a

"Brett" <no@spam.com> wrote in message
news:uV**************@TK2MSFTNGP14.phx.gbl...
<snip>
My point is that the structure is access only three times. Two writes and
one read. This isn't complicated and I don't have to worry about
accidentally assigning a value to the structure while it is being read
somewhere else. That can't happen since the flow is procedural. I
believe that is the red flag some of you were thinking about.


SO....Why are you making it a struct?

If you make it a class instead it will work.

Bill
Nov 17 '05 #13

P: n/a
Actually mutable structs are very useful. It is inefficient or inconvenient
at times to copy all fields from the old struct, instead of simply changing
one field. The confusion stems from the fact that C# does not distinguish in
any way between value type and reference type modifications. But the
compiler does catch attempts to modify a temporary struct returned from an
indexer.

For example, if you have a struct with 6 32-bit fields, and you wish to
change one field in each struct in a large array, only a mutable struct will
allow you to do this efficiently. A class would add heap overhead and an
extra pointer dereference.

Regards,
Frank Hileman

check out VG.net: http://www.vgdotnet.com
Animated vector graphics system
Integrated Visual Studio .NET graphics editor

"Bruce Wood" <br*******@canada.com> wrote in message
news:11**********************@g49g2000cwa.googlegr oups.com...
As Jonathan pointed out, structs should, in general, be immutable. To
change a value in a struct you should construct a new one using values
from the old one (except for the value you want to change). Creating
mutable structs is just asking for trouble. In fact, if you're creating
a mutable struct, it begs the question of why you made it a struct to
start with. Why isn't it a class?

Nov 17 '05 #14

P: n/a
> For example, if you have a struct with 6 32-bit fields, and you wish to
change one field in each struct in a large array, only a mutable struct
will allow you to do this efficiently. A class would add heap overhead and
an extra pointer dereference.
I don't believe that. How can the pointer dereference have such a
significant cost that it alone determines whether or not whole program is
efficient? If you are really to the point where that is your bottleneck, its
time to drop C# and go to a lower-level language.

--
Jonathan Allen
"Frank Hileman" <fr******@no.spamming.prodigesoftware.com> wrote in message
news:u0**************@TK2MSFTNGP10.phx.gbl... Actually mutable structs are very useful. It is inefficient or
inconvenient at times to copy all fields from the old struct, instead of
simply changing one field. The confusion stems from the fact that C# does
not distinguish in any way between value type and reference type
modifications. But the compiler does catch attempts to modify a temporary
struct returned from an indexer.

For example, if you have a struct with 6 32-bit fields, and you wish to
change one field in each struct in a large array, only a mutable struct
will allow you to do this efficiently. A class would add heap overhead and
an extra pointer dereference.

Regards,
Frank Hileman

check out VG.net: http://www.vgdotnet.com
Animated vector graphics system
Integrated Visual Studio .NET graphics editor

"Bruce Wood" <br*******@canada.com> wrote in message
news:11**********************@g49g2000cwa.googlegr oups.com...
As Jonathan pointed out, structs should, in general, be immutable. To
change a value in a struct you should construct a new one using values
from the old one (except for the value you want to change). Creating
mutable structs is just asking for trouble. In fact, if you're creating
a mutable struct, it begs the question of why you made it a struct to
start with. Why isn't it a class?


Nov 17 '05 #15

P: n/a
?? Every pointer dereference, every instruction, counts in a tight loop. The
lack of user-defined value types in Java (structs in C#) was a deficiency
for high performance applications, both in space (memory) and time. Struct
was added to C# for good reasons.

C# is fine for high performance applications, and we can assume it will get
better over time, especially with regards to structs.

Regards,
Frank Hileman

"Jonathan Allen" <x@x.x> wrote in message
news:Oj**************@TK2MSFTNGP14.phx.gbl...
For example, if you have a struct with 6 32-bit fields, and you wish to
change one field in each struct in a large array, only a mutable struct
will allow you to do this efficiently. A class would add heap overhead
and an extra pointer dereference.


I don't believe that. How can the pointer dereference have such a
significant cost that it alone determines whether or not whole program is
efficient? If you are really to the point where that is your bottleneck,
its time to drop C# and go to a lower-level language.

Nov 17 '05 #16

P: n/a
> ?? Every pointer dereference, every instruction, counts in a tight loop

Not true. If the loop isn't the bottleneck in your application, it doesn't
matter what is going on in it.

Honestly, can you think of a single time in your entire life that an extra
dereference in a loop actually made the difference between a usable and
unusable program?

Another consideration is what you are going to do with your N structs. Will
they really live solely in that array? Are you never going to sort it? Are
you never going to return a subset from a function call?

I'm asking because the first time you copy those structs to another
location, you've already lost your gain several times over. Copying a struct
is far more expensive than copying a pointer.

--
Jonathan Allen
"Frank Hileman" <fr******@no.spamming.prodigesoftware.com> wrote in message
news:%2****************@TK2MSFTNGP14.phx.gbl...
?? Every pointer dereference, every instruction, counts in a tight loop.
The lack of user-defined value types in Java (structs in C#) was a
deficiency for high performance applications, both in space (memory) and
time. Struct was added to C# for good reasons.

C# is fine for high performance applications, and we can assume it will
get better over time, especially with regards to structs.

Regards,
Frank Hileman

"Jonathan Allen" <x@x.x> wrote in message
news:Oj**************@TK2MSFTNGP14.phx.gbl...
For example, if you have a struct with 6 32-bit fields, and you wish to
change one field in each struct in a large array, only a mutable struct
will allow you to do this efficiently. A class would add heap overhead
and an extra pointer dereference.


I don't believe that. How can the pointer dereference have such a
significant cost that it alone determines whether or not whole program is
efficient? If you are really to the point where that is your bottleneck,
its time to drop C# and go to a lower-level language.


Nov 17 '05 #17

P: n/a

"Jonathan Allen" <x@x.x> wrote in message
news:OZ**************@TK2MSFTNGP10.phx.gbl...
?? Every pointer dereference, every instruction, counts in a tight loop
Not true. If the loop isn't the bottleneck in your application, it doesn't
matter what is going on in it.

Honestly, can you think of a single time in your entire life that an extra
dereference in a loop actually made the difference between a usable and
unusable program?


What do you mean by dereferencing the struct?

Another consideration is what you are going to do with your N structs.
Will they really live solely in that array? Are you never going to sort
it? Are you never going to return a subset from a function call?
What do you mean by returning a subset from a function?

I'm asking because the first time you copy those structs to another
location, you've already lost your gain several times over. Copying a
struct is far more expensive than copying a pointer.


And this is why the class should be used over a struct?

Should a struct ever be used verses a class?

Nov 17 '05 #18

P: n/a
If a loop is not a bottleneck -- why discuss performance? Let us assume the
developer can determine bottlenecks.

Yes, a single pointer dereference has made a critical difference in code I
have written. This type of code is common in graphics libraries, mathematics
libraries, processing huge data sets, scientific applications, collection
libraries, etc.

The increased memory usage of an array of object references (8 bytes heap
overhead per object + 4 bytes per array element pointer) decreases locality
of reference, which also impacts performance. Consider an 8 byte struct.
Substitute a class, and you have increased memory usage by 150%. If you have
an array with 100K elements, the struct version uses 800K bytes, and the
object version uses 2 meg. These types of differences can push you out of a
fast cache limit.

Structs in arrays can be sorted. If a struct is the same size as a pointer,
it is the same cost to copy. If used improperly large structs can be a
problem, but that is no reason to ban mutable structs. A better approach
would be to fix the language, so that a struct copy can be easily
distinguished from a reference (pointer) copy, reducing confusion.

Consider a struct with 8 properties, each internally consuming one byte of
storage. Suppose you need to modify one property. If the struct is
immutable, you must "modify" it by copying all 8 property values to a
constructor for a new struct taking 8 arguments. If the struct is mutable
the code is much simpler -- just change the property. So it is not just a
performance argument.

Frank

"Jonathan Allen" <x@x.x> wrote in message
news:OZ**************@TK2MSFTNGP10.phx.gbl...
?? Every pointer dereference, every instruction, counts in a tight loop


Not true. If the loop isn't the bottleneck in your application, it doesn't
matter what is going on in it.

Honestly, can you think of a single time in your entire life that an extra
dereference in a loop actually made the difference between a usable and
unusable program?

Another consideration is what you are going to do with your N structs.
Will they really live solely in that array? Are you never going to sort
it? Are you never going to return a subset from a function call?

I'm asking because the first time you copy those structs to another
location, you've already lost your gain several times over. Copying a
struct is far more expensive than copying a pointer.

--
Jonathan Allen

Nov 17 '05 #19

P: n/a
"Brett" <no@spam.com> wrote in message
news:%2***************@TK2MSFTNGP15.phx.gbl...
What do you mean by dereferencing the struct?
Internally, when you access an array element, if the array element contains
a reference to an object (declared as a class, not a struct) and you access
a field via a property in that object, there are two pointer dereferences:
one to get the address of the array memory block, and one to get the addess
of the field within the object.

By contrast, a struct is stored within the array memory block, so only one
pointer dereference is needed.

We are speaking at the level of the machine code. You cannot see this by
looking at the C# code, except by noticing what type of array you are
working with.

Should a struct ever be used verses a class?


If your abstraction already needs copy-by-value semantics, and it is not too
large, a struct is usually a better choice.

Consider a matrix class that overloads operator*. If you are overloading
operators, you probably want the return value to be a new matrix. In this
case, a struct makes perfect sense if the matrix is not too large and you
will be using lots of operators, as the struct is always passed by value,
and does not have the GC overhead that comes about from creating lots of
small objects.

The other reason for using a struct instead of a class is performance. Again
looking at a graphics package, a Point abstraction will consume less memory
and be faster as a struct, as the Point will typically be used in large
arrays.

We have found that a 6x2 float matrix is a better choice than an equivalent
class. This is larger than the usual choice for a struct, so it was
surprising.
Regards,
Frank Hileman

check out VG.net: http://www.vgdotnet.com
Animated vector graphics system
Integrated Visual Studio .NET graphics editor
Nov 17 '05 #20

P: n/a
> The increased memory usage of an array of object references (8 bytes heap
overhead per object + 4 bytes per array element pointer) decreases
locality of reference, which also impacts performance.
I still don't think the dereference is significant, but I buy the locality
argument. A poorly timed page fault and everything goes to hell.

--
Jonathan Allen
"Frank Hileman" <fr******@no.spamming.prodigesoftware.com> wrote in message
news:%2***************@TK2MSFTNGP15.phx.gbl... If a loop is not a bottleneck -- why discuss performance? Let us assume
the developer can determine bottlenecks.

Yes, a single pointer dereference has made a critical difference in code I
have written. This type of code is common in graphics libraries,
mathematics libraries, processing huge data sets, scientific applications,
collection libraries, etc.

The increased memory usage of an array of object references (8 bytes heap
overhead per object + 4 bytes per array element pointer) decreases
locality of reference, which also impacts performance. Consider an 8 byte
struct. Substitute a class, and you have increased memory usage by 150%.
If you have an array with 100K elements, the struct version uses 800K
bytes, and the object version uses 2 meg. These types of differences can
push you out of a fast cache limit.

Structs in arrays can be sorted. If a struct is the same size as a
pointer, it is the same cost to copy. If used improperly large structs can
be a problem, but that is no reason to ban mutable structs. A better
approach would be to fix the language, so that a struct copy can be easily
distinguished from a reference (pointer) copy, reducing confusion.

Consider a struct with 8 properties, each internally consuming one byte of
storage. Suppose you need to modify one property. If the struct is
immutable, you must "modify" it by copying all 8 property values to a
constructor for a new struct taking 8 arguments. If the struct is mutable
the code is much simpler -- just change the property. So it is not just a
performance argument.

Frank

Nov 17 '05 #21

P: n/a
The object is stored on the heap and GC takes place there. Is the struct
stored on the stack? I'd assume it is since it is value type. Also, how is
the stack cleared? By GC?

Thanks,
Brett

"Frank Hileman" <fr******@no.spamming.prodigesoftware.com> wrote in message
news:%2***************@TK2MSFTNGP15.phx.gbl...
If a loop is not a bottleneck -- why discuss performance? Let us assume
the developer can determine bottlenecks.

Yes, a single pointer dereference has made a critical difference in code I
have written. This type of code is common in graphics libraries,
mathematics libraries, processing huge data sets, scientific applications,
collection libraries, etc.

The increased memory usage of an array of object references (8 bytes heap
overhead per object + 4 bytes per array element pointer) decreases
locality of reference, which also impacts performance. Consider an 8 byte
struct. Substitute a class, and you have increased memory usage by 150%.
If you have an array with 100K elements, the struct version uses 800K
bytes, and the object version uses 2 meg. These types of differences can
push you out of a fast cache limit.

Structs in arrays can be sorted. If a struct is the same size as a
pointer, it is the same cost to copy. If used improperly large structs can
be a problem, but that is no reason to ban mutable structs. A better
approach would be to fix the language, so that a struct copy can be easily
distinguished from a reference (pointer) copy, reducing confusion.

Consider a struct with 8 properties, each internally consuming one byte of
storage. Suppose you need to modify one property. If the struct is
immutable, you must "modify" it by copying all 8 property values to a
constructor for a new struct taking 8 arguments. If the struct is mutable
the code is much simpler -- just change the property. So it is not just a
performance argument.

Frank

"Jonathan Allen" <x@x.x> wrote in message
news:OZ**************@TK2MSFTNGP10.phx.gbl...
?? Every pointer dereference, every instruction, counts in a tight loop


Not true. If the loop isn't the bottleneck in your application, it
doesn't matter what is going on in it.

Honestly, can you think of a single time in your entire life that an
extra dereference in a loop actually made the difference between a usable
and unusable program?

Another consideration is what you are going to do with your N structs.
Will they really live solely in that array? Are you never going to sort
it? Are you never going to return a subset from a function call?

I'm asking because the first time you copy those structs to another
location, you've already lost your gain several times over. Copying a
struct is far more expensive than copying a pointer.

--
Jonathan Allen


Nov 17 '05 #22

P: n/a
Brett <no@spam.com> wrote:
The object is stored on the heap and GC takes place there. Is the struct
stored on the stack? I'd assume it is since it is value type. Also, how is
the stack cleared? By GC?


Structs in arrays are stored on the heap (for most .NET applications
anyway; there are ways of storing arrays on the stack in C# and
presumably in C++ too). The stack isn't cleared by the garbage
collector - it's just cleared when the stack is popped. No data which
is on the stack is available after the stack is popped, so there's no
need for a complex system like garbage collection.

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

P: n/a
> The object is stored on the heap and GC takes place there. Is the struct
stored on the stack? I'd assume it is since it is value type. Also, how
is the stack cleared? By GC?
The stack is cleared when the function exits. Think of it as a stack of
boxes, the currently running function uses the top-most box. The function
that called it uses the next box. etc. Each box is created with enough room
to hold all the locals declared in the function.

Structs can be stored in the stack or inside a class. Or they can be boxed
and stored as if they were a class.

--
Jonathan Allen
"Brett" <no@spam.com> wrote in message
news:Oz**************@TK2MSFTNGP12.phx.gbl... The object is stored on the heap and GC takes place there. Is the struct
stored on the stack? I'd assume it is since it is value type. Also, how
is the stack cleared? By GC?

Thanks,
Brett

"Frank Hileman" <fr******@no.spamming.prodigesoftware.com> wrote in
message news:%2***************@TK2MSFTNGP15.phx.gbl...
If a loop is not a bottleneck -- why discuss performance? Let us assume
the developer can determine bottlenecks.

Yes, a single pointer dereference has made a critical difference in code
I have written. This type of code is common in graphics libraries,
mathematics libraries, processing huge data sets, scientific
applications, collection libraries, etc.

The increased memory usage of an array of object references (8 bytes heap
overhead per object + 4 bytes per array element pointer) decreases
locality of reference, which also impacts performance. Consider an 8 byte
struct. Substitute a class, and you have increased memory usage by 150%.
If you have an array with 100K elements, the struct version uses 800K
bytes, and the object version uses 2 meg. These types of differences can
push you out of a fast cache limit.

Structs in arrays can be sorted. If a struct is the same size as a
pointer, it is the same cost to copy. If used improperly large structs
can be a problem, but that is no reason to ban mutable structs. A better
approach would be to fix the language, so that a struct copy can be
easily distinguished from a reference (pointer) copy, reducing confusion.

Consider a struct with 8 properties, each internally consuming one byte
of storage. Suppose you need to modify one property. If the struct is
immutable, you must "modify" it by copying all 8 property values to a
constructor for a new struct taking 8 arguments. If the struct is mutable
the code is much simpler -- just change the property. So it is not just a
performance argument.

Frank

"Jonathan Allen" <x@x.x> wrote in message
news:OZ**************@TK2MSFTNGP10.phx.gbl...
?? Every pointer dereference, every instruction, counts in a tight loop

Not true. If the loop isn't the bottleneck in your application, it
doesn't matter what is going on in it.

Honestly, can you think of a single time in your entire life that an
extra dereference in a loop actually made the difference between a
usable and unusable program?

Another consideration is what you are going to do with your N structs.
Will they really live solely in that array? Are you never going to sort
it? Are you never going to return a subset from a function call?

I'm asking because the first time you copy those structs to another
location, you've already lost your gain several times over. Copying a
struct is far more expensive than copying a pointer.

--
Jonathan Allen



Nov 17 '05 #24

P: n/a
We were talking about structs in arrays. Those would always be on the heap,
not the stack. If you are talking about a value type used as a parameter or
local variable, or a temporary returned by an operator overload, then you
are potentially looking at the stack.

The stack is allocated according to the number and size of parameters, local
variables, and temporaries used by a method. When the method returns the
stack space is immediately released and reused for the next method call.
Basically it is just a preallocated block of memory with the current offset
kept in a register than is incremented and decremented. Often temporaries,
local variables, and parameters wind up in registers instead, and take no
space on the stack. This is the ideal situation.

The .NET GC is fast. But it can never beat the memory size and speed of
value types in local variables or parameters, as they may be in registers.
Even if they are on the stack, the .net heap allocater continues to move
into new memory addresses as it allocates new objects, until a GC is
triggered, whereas the stack constantly reuses a smaller area of memory, so
you get better locality of reference. The .NET allocator and GC are so fast
sometimes the heap seems similar to a stack over a larger span of memory.
Look at the timeline view in the CLRProfiler tool.

Regards,
Frank Hileman

"Brett" <no@spam.com> wrote in message
news:Oz**************@TK2MSFTNGP12.phx.gbl...
The object is stored on the heap and GC takes place there. Is the struct
stored on the stack? I'd assume it is since it is value type. Also, how
is the stack cleared? By GC?

Thanks,
Brett

Nov 17 '05 #25

P: n/a
> My point is that the structure is access only three times. Two writes and
one read. This isn't complicated and I don't have to worry about
accidentally assigning a value to the structure while it is being read
somewhere else. That can't happen since the flow is procedural.
I believe that is the red flag some of you were thinking about.


The "red flag" has nothing to do with concurrency. It has instead to do
with semantics. What's missing in this conversation is that nowhere
have you indicated why you _need_ a struct, rather than a class.
structs in C# are very useful, but they are useful for specific reasons
in specific situations. Nothing you've outlined so far indicates that
you're in one of those situations. You may be, but we just haven't
heard why you need a struct here.

So when do you _need_ a struct?

First and foremost, you need a struct when you need something that will
act like a native (value) type: whenever you assign it, it gets copied.
When you pass it as a method argument, it gets copied. In general you
don't care about the _identity_ of the thing: this-one-versus-that-one;
all you really care about its its _value_ (thus the name). Some
examples of structs I've created: a Fraction class, a Measure class
that holds a quantity and a unit of measure. In both of these cases,
Fractions and Measures act like values, like ints or doubles. I don't
_want_ to have a specific instance of 3 3/4 somewhere, with everyone
pointing to it and modifying it. When I assign a Fraction to a variable
I want to create a new Fraction with the same value.

Second, and less common, you may choose to use a struct to improve the
efficiency of your application. This is the one that gets everyone into
trouble with structs.

A word about efficiency: CPU-intensive applications aside (and there
aren't many of those... really, there aren't), you get far, far more
bang for your buck looking for efficiencies in your program's _design_
than you ever will tweaking code. Yes, there are some areas of
programming where both design and tweaking code are required, but as I
said, not many. It's hard to convince newbies of this. So many new
programmers just _love_ poring over their code, tweaking an instruction
here, eliminating a variable there, obvlivious to the fact that there
are huge gains to be had by modifying design or data structures, and
that all of that hand-work they're doing was probably done by the
compiler or the JITter, anyway.

In C#, this manifests itself as a mad dash to turn things into structs
that really have no business being structs, so that the program will be
"more efficient." It also manifests itself as odd questions in
newsgroups, questions like, "Why would anyone want to use a class if
they're less efficient?" A little knowledge, as the saying goes, is a
dangerous thing.

Of course, in using a struct where a class is really needed, one has to
make the struct mutable (give it set accessors), and then the trouble
really starts.

The "red flag" that Ted Miller mentioned is this: structs are useful,
but you don't often run across situations in which you need them. If
you don't need a struct, you're probably better off using a class,
particularly if you don't have a solid understanding of value semantics
versus reference semantics. The problems you're having are likely an
indication that you really want a class, not a struct.

Furthermore, if you create a mutable struct (a struct with settable
properties), then you had better have a _very_ solid understanding of
value semantics and how they differ from reference semantics.
Otherwise, you're going to find strange things happening in your code,
and the few cycles you may have saved by using a struct (if you save
any at all) will be offset by the hours of head-scratching you'll
endure trying to get your program to work. (The upside is that once
you've gone through that pain, you'll either hate structs or have a
solid understanding of value semantics--or both.)

I would make the same claim about exposing mutable structs as part of
the public contract of a DLL for others' use. You had better be sure
that your callers have a _solid_ understanding of .NET value semantics.
Either that or be ready with arguments as to why you had to make
mutable structs publicly visible. Yes, I know that Microsoft did it.
They had very good reasons why they did it. Nonetheless, it still
confuses the %&$# out of a lot of programmers.

Use classes. Use structs only when classes won't do.

Nov 17 '05 #26

P: n/a
> My point is that the structure is access only three times. Two writes and
one read. This isn't complicated and I don't have to worry about
accidentally assigning a value to the structure while it is being read
somewhere else. That can't happen since the flow is procedural.
I believe that is the red flag some of you were thinking about.


The "red flag" has nothing to do with concurrency. It has instead to do
with semantics. What's missing in this conversation is that nowhere
have you indicated why you _need_ a struct, rather than a class.
structs in C# are very useful, but they are useful for specific reasons
in specific situations. Nothing you've outlined so far indicates that
you're in one of those situations. You may be, but we just haven't
heard why you need a struct here.

So when do you _need_ a struct?

First and foremost, you need a struct when you need something that will
act like a native (value) type: whenever you assign it, it gets copied.
When you pass it as a method argument, it gets copied. In general you
don't care about the _identity_ of the thing: this-one-versus-that-one;
all you really care about its its _value_ (thus the name). Some
examples of structs I've created: a Fraction class, a Measure class
that holds a quantity and a unit of measure. In both of these cases,
Fractions and Measures act like values, like ints or doubles. I don't
_want_ to have a specific instance of 3 3/4 somewhere, with everyone
pointing to it and modifying it. When I assign a Fraction to a variable
I want to create a new Fraction with the same value.

Second, and less common, you may choose to use a struct to improve the
efficiency of your application. This is the one that gets everyone into
trouble with structs.

A word about efficiency: CPU-intensive applications aside (and there
aren't many of those... really, there aren't), you get far, far more
bang for your buck looking for efficiencies in your program's _design_
than you ever will tweaking code. Yes, there are some areas of
programming where both design and tweaking code are required, but as I
said, not many. It's hard to convince newbies of this. So many new
programmers just _love_ poring over their code, tweaking an instruction
here, eliminating a variable there, obvlivious to the fact that there
are huge gains to be had by modifying design or data structures, and
that all of that hand-work they're doing was probably done by the
compiler or the JITter, anyway.

In C#, this manifests itself as a mad dash to turn things into structs
that really have no business being structs, so that the program will be
"more efficient." It also manifests itself as odd questions in
newsgroups, questions like, "Why would anyone want to use a class if
they're less efficient?" A little knowledge, as the saying goes, is a
dangerous thing.

Of course, in using a struct where a class is really needed, one has to
make the struct mutable (give it set accessors), and then the trouble
really starts.

The "red flag" that Ted Miller mentioned is this: structs are useful,
but you don't often run across situations in which you need them. If
you don't need a struct, you're probably better off using a class,
particularly if you don't have a solid understanding of value semantics
versus reference semantics. The problems you're having are likely an
indication that you really want a class, not a struct.

Furthermore, if you create a mutable struct (a struct with settable
properties), then you had better have a _very_ solid understanding of
value semantics and how they differ from reference semantics.
Otherwise, you're going to find strange things happening in your code,
and the few cycles you may have saved by using a struct (if you save
any at all) will be offset by the hours of head-scratching you'll
endure trying to get your program to work. (The upside is that once
you've gone through that pain, you'll either hate structs or have a
solid understanding of value semantics--or both.)

I would make the same claim about exposing mutable structs as part of
the public contract of a DLL for others' use. You had better be sure
that your callers have a _solid_ understanding of .NET value semantics.
Either that or be ready with arguments as to why you had to make
mutable structs publicly visible. Yes, I know that Microsoft did it.
They had very good reasons why they did it. Nonetheless, it still
confuses the %&$# out of a lot of programmers.

Use classes. Use structs only when classes won't do.

Nov 17 '05 #27

This discussion thread is closed

Replies have been disabled for this discussion.