int number = new int();

  • Thread starter Thread starter Tony Johansson
  • Start date Start date
T

Tony Johansson

Hello!

If I write this statement
int number = new int();
I don't get compiler error or run time error
but how will the compiler read such a statement ?

For example will number be a reference to a new int on the heap?

//Tony
 
Tony Johansson said:
If I write this statement
int number = new int();
I don't get compiler error or run time error
but how will the compiler read such a statement ?

For example will number be a reference to a new int on the heap?

No. The above is the same as writing:

int number = 0;

"new" doesn't imply "create object on the heap" in C# - it just implies
"call the constructor". For value types, that doesn't create a new
object, it just initializes a new value.
 
Hi,

int is in C# a shortcut for Int32 (even in 64bits computers).

Int32 is a structure they never are placed on the heap.

Cor
 
int is in C# a shortcut for Int32 (even in 64bits computers).
Correct.

Int32 is a structure they never are placed on the heap.

Well, they're on the heap:
1) If they're boxed
2) If they're part of another value which is on the heap

For instance:

class Foo
{
int x;
}

Here, any instance of Foo lives on the heap, including its x variable.

"Structs live on the stack" is a myth.
See http://pobox.com/~skeet/csharp/memory.html for more info.

Jon
 
Hello!

This is not really true:
Int32 is a structure they never are placed on the heap.
because of
If you box an int like.
int number = 1;
object o = number; // here number is still a value type of type Int32 but is
copied to heap when being boxed
// so o is stored on the stack and will
reference number which is stored on the heap.

//Tony
 
This is not really true:> Int32 is a structure they never are placed on the heap.

because of
If you box an int like.
int number = 1;
object o = number; // here number is still a value type of type Int32 but is
copied to heap when being boxed
                              // so o is stored on the stack and will
reference number which is stored on the heap.

No, the variable "number" is still on the stack. The value of "o" is a
reference to a boxed copy of the value which number had at the time of
the assignment. If you change the value of number, that won't be seen
if you then look at o.

Jon
 
Hello!

Assume you have the following.
int number = 1;
object o = number;
If you here change the value of number it won't change what o is refering to
because that
is stored on the heap.
So we have one value of number which is stored on the stack and when we do
object o = number
a copy of this actual value number is put on the heap. f we now change
number by using this statement
number = 2;
the number that o is refering to is still 1;

I almost 99.99 % sure that this is correct.

//Tony

This is not really true:> Int32 is a structure they never are placed on
the heap.

because of
If you box an int like.
int number = 1;
object o = number; // here number is still a value type of type Int32 but
is
copied to heap when being boxed
// so o is stored on the stack and will
reference number which is stored on the heap.

No, the variable "number" is still on the stack. The value of "o" is a
reference to a boxed copy of the value which number had at the time of
the assignment. If you change the value of number, that won't be seen
if you then look at o.

Jon
 
Assume you have the following.
int number = 1;
object o = number;
If you here change the value of number it won't change what o is referingto
because that is stored on the heap.
Yes.

So we have one value of number which is stored on the stack and when we do
object o = number
a copy of this actual value number is put on the heap.
Yes.

If we now change number by using this statement
number = 2;
the number that o is refering to is still 1;
Correct.

I almost 99.99 % sure that this is correct.

Absolutely. I was merely correcting this statement that you made
before:

// so o is stored on the stack and will
// reference number which is stored on the heap.

"o" doesn't reference "number". It reference an object which was
created with a value which happened to be the value of "number" at the
time. The two variables are independent immediately after the
assignment.

Jon
 
Hello!

I just wonder if it's then correct to say that
Int32 is a structure they never are placed on the heap.
I mean when you are boxing a copy is actually stored on the heap
as I described

//Tony


Assume you have the following.
int number = 1;
object o = number;
If you here change the value of number it won't change what o is refering
to
because that is stored on the heap.
Yes.

So we have one value of number which is stored on the stack and when we do
object o = number
a copy of this actual value number is put on the heap.
Yes.

If we now change number by using this statement
number = 2;
the number that o is refering to is still 1;
Correct.

I almost 99.99 % sure that this is correct.

Absolutely. I was merely correcting this statement that you made
before:

// so o is stored on the stack and will
// reference number which is stored on the heap.

"o" doesn't reference "number". It reference an object which was
created with a value which happened to be the value of "number" at the
time. The two variables are independent immediately after the
assignment.

Jon
 
I just wonder if it's then correct to say that> Int32 is a structure theynever are placed on the heap.

I mean when you are boxing a copy is actually stored on the heap
as I described

Indeed. It's also on the heap when it's part of another object. See my
response to Cor.

(Even a local variable can be on the heap if it's captured as part of
an iterator block or anonymous function...)

Jon
 
OD said:
that's just like an optical effect, it seems to be on the heap but
strictly speaking you can't say the int is on the heap in both cases
you're listing.

The data which represents the integer lives somewhere in memory, right?
That memory is on the heap. Therefore the value is on the heap, to my
mind. It's certainly not on the stack.
It can be confusing for beginners.
In case 1) the value is transformed into an object and this object is
stored on the heap, initial value is not really on the heap.

No, but the value *in the box* is on the heap. The object contains the
same data (as a copy) as the original value.
In case 2) the value is localy stored in a structure (parent object's
memory area) that is on the heap, it is not really and directly on the
heap by itself.

I didn't say it was on the heap *by itself*. I said it was on the heap.
I believe that to be entirely accurate, and with appropriate
explanation (linked in the post) I don't think it confuses people.
Compare that with the "structs are on the stack, classes are on the
heap" myth: at that point there's a contradiction when you consider a
class containing a value type instance variable.
It's a bit like saying an egg can fly... if you bring it with you in a
plane ! :-)

No, it would be like saying an egg can be 10,000 feet above the ground
- which it certainly can if it's on a plane.
 
hi group,

is it really important to know if some object goes to the heap or to the
stack?

thanks, Carlos

I just wonder if it's then correct to say that> Int32 is a structure they never are placed on the heap.

I mean when you are boxing a copy is actually stored on the heap
as I described

Indeed. It's also on the heap when it's part of another object. See my
response to Cor.

(Even a local variable can be on the heap if it's captured as part of
an iterator block or anonymous function...)

Jon
 
xcal said:
is it really important to know if some object goes to the heap or to the
stack?

That's a very perceptive question. Arguably not, so long as the
CLR/framework/compiler hides the details in an efficient enough manner.

See http://csharpindepth.com/ViewNote.aspx?NoteID=41

However, it can occasionally be an interesting way of thinking about
other aspects of behaviour. It's easy enough to see that if data is to
be shared between threads, it has to be on the heap - and conversely,
that if data is only on the stack, it's threadsafe. (Assuming no
*really* nasty hacks, admittedly.)
 
Peter Duniho said:
[...]
However, it can occasionally be an interesting way of thinking about
other aspects of behaviour. It's easy enough to see that if data is to
be shared between threads, it has to be on the heap - and conversely,
that if data is only on the stack, it's threadsafe. (Assuming no
*really* nasty hacks, admittedly.)

Well, that's interesting.

I'm still not sure I'd go around assuming that data on the stack is
threadsafe, but until you wrote the above, I had no idea that you weren't
allowed to use by-reference arguments in anonymous methods.

You can:

using System;

class Test
{
delegate void Foo(ref int i);

public static void Main()
{
Foo f = delegate (ref int x) { x = 10; };

int j = 0;
f(ref j);
Console.WriteLine(j);
}
}

Not sure what you meant, but the thread-safe aspect seems sensible to
me - if the data is on the stack, how can another thread get at it?
Note that I'm talking about the *actual data* here - if you happen to
have a reference to an object, then of course a different thread may be
able to modify that object's data if it's got a reference to it.
As for "*really* nasty hacks" go, I guess that depends on your
definition. All that's really necessary in order to get stack-stored data
from one thread to another is the use of unsafe code (i.e. pointers).
It's not like you have to write self-modifying code, or generate your own
IL, or otherwise do an end-around of the compiler.

Unsafe code at both sides (I suspect) - which means it would at least
be deliberate.
I'm of the general opinion that any use of unsafe code could be considered
"nasty", but I have to admit that not everyone agrees. And personally, I
think maybe unsafe code is simply "nasty", not necessarily "*really*
nasty".

So, what's _your_ definition of "*really* nasty hacks"? I assume it
includes the use of unsafe code. :)

Not necessarily - but anything which is deliberately making stack data
available to a different thread is really nasty (and brittle) IMO.
 
OD said:
Why can't you just say "ok, i was wrong" ?

Because I don't think I was. The "value types are on the stack;
reference types are on the heap" is a myth which confuses people. I try
to set the record straight. I've helped a number of people on this
matter. Why would I now say I was wrong, if I still don't believe I
was?
 
Peter Duniho said:
That's not what I meant:

Action Method(ref int i)
{
return delegate { i = i + 1; };
}

That's not allowed, for good reason. That is, it prohibits the one
dangerous use case I can think of that might have led to access to stack
data for one thread from another.

Right. Not only is it dangerous in terms of multiple threads, but even
in a single thread I don't see how it could work.
Note that the above example I'm talking about _can_ be easily implemented
using unsafe code, simply by passing a pointer instead of a by-ref
argument. The delegate returned could then be passed to a thread that
executes it and, vo?la, it's modifying data on a different thread's stack.

Yes - fortunately both sides would need to know about it (as described
below).
I'm not sure what you mean by "both sides". It is possible for the code
managing the thread itself to be unaware of the access, but yes...the code
actually _doing_ the access (executed by the thread in the form of a
delegate) would necessarily need to be aware, because it would have to be
unsafe, as would the code providing access, because it also would have to
be usafe.

Exactly. Both the caller and the callee would need to be using unsafe
code, and explicitly handle the pointers. My point is that you're
unlikely to *accidentally* get into this situation.
[...]
So, what's _your_ definition of "*really* nasty hacks"? I assume it
includes the use of unsafe code. :)

Not necessarily - but anything which is deliberately making stack data
available to a different thread is really nasty (and brittle) IMO.

Well, the code passing the reference to the data may not know that the
data will be accessed on a different thread, while the code accessing the
data on a different thread may not know that the data came from the
stack. Both sides would have to be marked as unsafe, but there might not
be any deliberate intent to make stack data available to a different
thread (willfull ignorance would be more descriptive in that scenario :) ).

Mmm. I'm pleased that I can't easily *accidentally* let this kind of
thing happen.
 
hi Jon and Peter,

Thanks for your comments, these things are very complicated affairs.

Carlos.

Jon Skeet said:
Peter Duniho said:
That's not what I meant:

Action Method(ref int i)
{
return delegate { i = i + 1; };
}

That's not allowed, for good reason. That is, it prohibits the one
dangerous use case I can think of that might have led to access to stack
data for one thread from another.

Right. Not only is it dangerous in terms of multiple threads, but even
in a single thread I don't see how it could work.
Note that the above example I'm talking about _can_ be easily implemented
using unsafe code, simply by passing a pointer instead of a by-ref
argument. The delegate returned could then be passed to a thread that
executes it and, vo?la, it's modifying data on a different thread's
stack.

Yes - fortunately both sides would need to know about it (as described
below).
I'm not sure what you mean by "both sides". It is possible for the code
managing the thread itself to be unaware of the access, but yes...the code
actually _doing_ the access (executed by the thread in the form of a
delegate) would necessarily need to be aware, because it would have to be
unsafe, as would the code providing access, because it also would have to
be usafe.

Exactly. Both the caller and the callee would need to be using unsafe
code, and explicitly handle the pointers. My point is that you're
unlikely to *accidentally* get into this situation.
[...]
So, what's _your_ definition of "*really* nasty hacks"? I assume it
includes the use of unsafe code. :)

Not necessarily - but anything which is deliberately making stack data
available to a different thread is really nasty (and brittle) IMO.

Well, the code passing the reference to the data may not know that the
data will be accessed on a different thread, while the code accessing the
data on a different thread may not know that the data came from the
stack. Both sides would have to be marked as unsafe, but there might not
be any deliberate intent to make stack data available to a different
thread (willfull ignorance would be more descriptive in that scenario
:) ).

Mmm. I'm pleased that I can't easily *accidentally* let this kind of
thing happen.

--
Jon Skeet - <[email protected]>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon.skeet
C# in Depth: http://csharpindepth.com
 
Jon Skeet [C# MVP] kirjoitti:
Because I don't think I was. The "value types are on the stack;
reference types are on the heap" is a myth which confuses people. I try
to set the record straight. I've helped a number of people on this
matter. Why would I now say I was wrong, if I still don't believe I
was?
I think OD is right. When the program sees int, it is always a value
that comes from the stack. There is something on heap that is boxed or
inside a class, but the new int (like the original message asked) is
created onto stack.
 
Peter Duniho said:
Do you mean in theory? Or based on some specifics about how the CLR works?

To me, it's obvious in theory how it'd work. But I don't know enough
about the CLR to know whether it'd support that sort of thing. It may be
that in any language, you have to use pointers rather than references to
implement the behavior.

Well, consider this program:

class Test
{
public static void Main()
{
Action foo = Foo();
foo();
}

public static Action Foo()
{
int i = 5;
return Bar(ref i);
}

public static Action Bar(ref int x)
{
return (Action) delegate()
{
x++;
Console.WriteLine(x);
}
}
}

What would you expect running that to do? I can't see how it can
compile and run without blowing up (or being unpredictable). The
variable x can't be captured in the normal way, because effectively the
variable itself is being passed in (rather than an initial value).
[...]
Exactly. Both the caller and the callee would need to be using unsafe
code, and explicitly handle the pointers. My point is that you're
unlikely to *accidentally* get into this situation.

Well, it seems to me that there's a broad gap between "accidently
implemented" and "nasty hack". That was the gist of my comment. I agree
it'd be a hack, but I've seen far nastier (probably been responsible for a
few over the years, for that matter...not that I'm proud of that :) ). I
was mostly just curious what your threshold for "nasty hack" is...sounds
like it's pretty low. :) (Not that there's anything wrong with that...to
each their own).

Well, anything involving pointers would make me suspicious to start
with - and anything relying on a particular stackframe in one thread
still being around by the time another thread executed some code just
sounds pretty evil to me.
 
I think OD is right. When the program sees int, it is always a value
that comes from the stack.

No, that's not true. Consider:

public class Foo
{
int x;

public void Bar()
{
int y = x;
}
}

Now, where does the value y is initialized with come from? The heap -
because that's where the value of x is stored.
There is something on heap that is boxed or
inside a class, but the new int (like the original message asked) is
created onto stack.

The right hand side of the statement in the original question is
(logically, at least) evaluated on the stack. But the target of the
assignment could well be on the heap.

Let's go back to Cor's original statement which I disagreed with:
"Int32 is a structure they never are placed on the heap."

Now consider the class above again:
1) What is the type of the variabe x?
2) Where does its value live, i.e. where is it "placed"?

My answers are "int, i.e. Int32" and "on the heap" - which directly
contradicts Cor's statement.

What are your answers to the above two questions?

Jon
 

Ask a Question

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

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

Ask a Question

Similar Threads


Back
Top