arrays = pointers?

Z

Zytan

Yes, and that's why as soon as your program contains an "unsafe"
section it needs elevated privileges to run that section. The CLR
won't allow any Tom-Dick-or-Harry program from the Web to run unsafe
code (unless you're foolish enough to set up your machine's code-based
security that way).

Yes, i see.
Yes, and that's why C# also provides mechanisms to "pin" objects when
calling across to unmanaged (good ol' Win32) code: while code outside
the CLR is looking at / manipulating managed data, the GC has to be
told not to move that data during compaction or... boom!
Cool!

It is for ex-C hacks like us. I freely admit that I, too, saw "struct"
and thought, "Oh, a lightweight class." No, it's not. It acts, as you
said, like a native type, which is tremendously useful, but if you
abuse it by trying to create a "light" class then you will suddenly
find your code becoming tortured and incomprehensible.

Well, i never use struct as a class, so i won't run into that
problem. But, realizing structs were lightweight classes for C++
helped me a lot. But, this changes for C#.
There are lots of threads here about value versus reference
semantics... I don't really want to hijack this thread with that
discussion. Suffice to say that the distinction _is_ a big deal, but
once you "get it" it's not complicated.

Ok. I will research this. thanks.

Zytan
 
Z

Zytan

Right. You can get the integral value of a reference using IntPtr... but
there's no typesafe way to make an integer back into a reference (though you
can use an unsafe pointer to do so). Still, you can see the actual
in-memory address, and watch to see how it moves (hint, one easy way to make
it move is pinning it with the GCHandle constructor overload).
Cool!

As long as you have a reference, C# (actually the CLR) tracks it and keeps
it up-to-date. As soon as you put the address in some other variable, like
an integer, the CLR no longer knows you're using it, so the object can be
moved or deleted. C++/CLI actually has a pointer type (interior_ptr) which
allows pointer arithmetic and automatically follows objects moved by the
CLR.

I see. thanks for the information!

Zytan
 
Z

Zytan

Yes, the reference itself is copied, but not what it references. How
Not quite. There are other value types - DateTime, GUID etc. Basically,
in MSDN, if the description is of a "struct" that means a value type.
If it's of a "class" that means a reference type.

Yup, got it. This is what I was thinking. Thanks!

Zytan
 
Z

Zytan

Yes, the native types are value types, but not everything else are
reference types.

You can easily see the difference in the documentation. Value types are
listed as structures, for example "Int32 structure" and reference types
are listed as classes, for example "String class".

Thank you, Göran. I was just looking there and noticed Int32, and I
got it, and you guys have confirmed it. structs are value, classes
are references. Easy enough, and makes sense. thanks again!

Zytan
 
?

=?ISO-8859-1?Q?Arne_Vajh=F8j?=

Zytan said:
Right, the reference (pointer) is passed by value, and cannot change,
but what it refers to can change. This is what i *meant* by 'classes
are passed by reference', and i see the difference.

Maybe the following comparison would give some insight:

C# C
void m(valtyp v) void f(typ v)
void m(ref valtyp v) void f(typ *v)
void m(reftyp v) void f(typ *v)
void m(ref reftyp v) void f(typ **v)

Arne
 
B

Ben Voigt

Well, i never use struct as a class, so i won't run into that
problem. But, realizing structs were lightweight classes for C++
helped me a lot. But, this changes for C#.

C++ structs aren't lightweight classes, they are fully classes. The *only*
difference is that the struct body begins with an implicit "public:" while
the class body begins with implicit "private:". Structs have all the
capabilities that a "heavyweight" class does, virtual class, multiple
inheritance, virtual inheritance, pointers to members, templated members,
etc.

C# structs are different though... and C++/CLI did a good job of making this
evident. The rough correspondance is as follows:

C# struct (default internal) = C++/CLI value class (default private) =
C++/CLI value struct (default public)
C# class (default internal) = C++/CLI ref class (default private) = C++/CLI
ref struct (default public)
 
Z

Zytan

Maybe the following comparison would give some insight:
C# C
void m(valtyp v) void f(typ v)
void m(ref valtyp v) void f(typ *v)
void m(reftyp v) void f(typ *v)
void m(ref reftyp v) void f(typ **v)

Yes, Arne, I follow. And it's basically true. But note that this
*implies*:
reference passing of a value type = value passing of a reference type.
and that's incorrect.

http://www.yoda.arachsys.com/csharp/parameters.html
scroll down to:
Sidenote: what is the difference between passing a value object by
reference and a reference object by value?

Zytan
 
Z

Zytan

C++ structs aren't lightweight classes, they are fully classes. The *only*
difference is that the struct body begins with an implicit "public:" while
the class body begins with implicit "private:". Structs have all the
capabilities that a "heavyweight" class does, virtual class, multiple
inheritance, virtual inheritance, pointers to members, templated members,
etc.

Right. I knew that. I was just using another poster's term of
'lightweight'. I agree they are exactly the same besides for the
default privileges. And this helped me a lot to understand what
classes were all about.

Zytan
 
?

=?ISO-8859-1?Q?Arne_Vajh=F8j?=

Zytan said:
Yes, Arne, I follow. And it's basically true. But note that this
*implies*:
reference passing of a value type = value passing of a reference type.
and that's incorrect.

It does not imply that. It implies that the best C equivalent
of both is a pointer.
http://www.yoda.arachsys.com/csharp/parameters.html
scroll down to:
Sidenote: what is the difference between passing a value object by
reference and a reference object by value?

It is a very good description of the difference between
reference types and value types in C#, but in the comparison
with C the point is slightly different.

If we use C++ to avoid malloc (and ignore the
fact that C++ has the ref specifier &):

void m(reftyp v)
{
v = new reftyp();
}

is:

void m(typ *v)
{
v = new typ();
}

but:

void m(ref valtyp v)
{
v = new valtyp();
}

is:

void m(typ *v)
{
*v = *(new typ());
}

The difference is not so much in the declaration but
in the meaning of the = operator.

Arne
 
P

Peter Duniho

I guess i think of C references as pointers internally. I think of
them as one and the same, so it doesn't make any difference to me.
But, for C#, I'd like to get in-the-know with what the proper
terminology is.

I don't think that's really what Tom was talking about though. A "C
reference" is a particular syntax that hides the pointer syntax, but still
acts like a pointer. On the other hand, a general "reference" is simply a
way of saying that one thing refers to another. I think it was this more
general meaning that Tom was talking about.
yes. They are references in a literal sense of the term, so it all
makes sense. I'll stop using the term 'pointer'.

Personally, I think that it's hard to say that they are "references in a
literal sense of the term". After all, as far as I know all uses of the
word "reference" in programming use it in a literal sense of the term.
That is, they refer to something else (as opposed to being the thing to
which they refer).

I think that the real reason to not use the term "pointer" is that that's
not the term that the .NET documentation uses, nor is it the term that all
the other .NET programmers are using. It's really just about using the
right jargon given the context.

As far as conceptualizing what a .NET "reference" is, I suppose that's
more open. Personally, I tend to think of them as "handles", because
that's the term the Mac OS used way back when, when I first ran into the
idea of a relocatable pointer. Of course, in that situation you had to
dereference the handles manually, but the concept was the same.

I guess in reality, the best way to conceptualize a .NET reference is as a
relocatable pointer, since that's really what it is, somehow. I don't
actually know the underlying implementation. Is it actually a pointer to
a pointer, where .NET automatically handles the double dereference for
you? Is it a simple pointer, but one for which .NET maintains some table
of references to copies of the pointer and updates if the underlying block
of memory has to be relocated? The latter seems overly complicated, but
does have certain run-time performance advantages over the former. For
all I know it's some entirely different mechanism from either of those two.

But regardless of the mechanism, a .NET reference is a pointer to a block
of memory that is relocatable. Thus, a relocatable pointer.

Pete
 
G

Guest

Peter said:
I think that the real reason to not use the term "pointer" is that
that's not the term that the .NET documentation uses, nor is it the term
that all the other .NET programmers are using. It's really just about
using the right jargon given the context.

The documentation actually uses the term "pointer", but that is used for
pointers. :)
I guess in reality, the best way to conceptualize a .NET reference is as
a relocatable pointer, since that's really what it is, somehow. I don't
actually know the underlying implementation. Is it actually a pointer
to a pointer, where .NET automatically handles the double dereference
for you? Is it a simple pointer, but one for which .NET maintains some
table of references to copies of the pointer and updates if the
underlying block of memory has to be relocated? The latter seems overly
complicated, but does have certain run-time performance advantages over
the former. For all I know it's some entirely different mechanism from
either of those two.

Yes, it's much simpler than any of those two. The inner workings of a
reference is just a pointer, nothing more. What makes a reference
different from a pointer is simply how the compiler allows you to use it.
 
Z

Zytan

I don't think that's really what Tom was talking about though. A "C
reference" is a particular syntax that hides the pointer syntax, but still
acts like a pointer. On the other hand, a general "reference" is simply a
way of saying that one thing refers to another. I think it was this more
general meaning that Tom was talking about.

Understood. I am stuck thinking 'reference = pointer', since in C
that's what it is internally. But, you're right, the word reference
just means a reference to something. In C, it happens to be
implemented as a pointer.
Personally, I think that it's hard to say that they are "references in a
literal sense of the term". After all, as far as I know all uses of the
word "reference" in programming use it in a literal sense of the term.
That is, they refer to something else (as opposed to being the thing to
which they refer).

You're right.

My meaning of 'reference' was 'C style pointer hidden reference', and
that's wrong.
I think that the real reason to not use the term "pointer" is that that's
not the term that the .NET documentation uses, nor is it the term that all
the other .NET programmers are using. It's really just about using the
right jargon given the context.

Precisely why I am asking the question. Thanks.
As far as conceptualizing what a .NET "reference" is, I suppose that's
more open. Personally, I tend to think of them as "handles", because
that's the term the Mac OS used way back when, when I first ran into the
idea of a relocatable pointer. Of course, in that situation you had to
dereference the handles manually, but the concept was the same.

I see, much like Win32. It was about the only way to implement data
encapsulation with no OOP in C. Handles would be a good term to use,
as well.
I guess in reality, the best way to conceptualize a .NET reference is as a
relocatable pointer, since that's really what it is, somehow. I don't
actually know the underlying implementation.

Yes, I agree.
But regardless of the mechanism, a .NET reference is a pointer to a block
of memory that is relocatable. Thus, a relocatable pointer.

Thanks Pete
 
G

Guest

Peter said:
I don't think that's really what Tom was talking about though. A "C
reference" is a particular syntax that hides the pointer syntax, but
still acts like a pointer.

A C++ reference - it is not in C.

Arne
 
Z

Zytan

I guess i think of C references as pointers internally. I think of
A C++ reference - it is not in C.

Yes, sorry. I think I sometimes call C/C++ just as C by accident.
But I did mean C++ reference.

Zytan
 
P

Peter Duniho

The documentation actually uses the term "pointer", but that is used for
pointers. :)

Sorry...I didn't think it was necessary to explicitly state that I was
simply talking about what the .NET documentation uses to describe
references. Of course it uses the word "pointer" elsewhere, just as it
uses all sorts of other words that also do not describe .NET references.
Yes, it's much simpler than any of those two. The inner workings of a
reference is just a pointer, nothing more. What makes a reference
different from a pointer is simply how the compiler allows you to use it.

It is obviously not "just a pointer". Either the compiler, or the .NET
Framework, or both, hide the inner workers from the programmer. But for
the reference to be relocatable, *some* kind of extra work has to be
done. Whether that is for the reference to be a pointer to a pointer, or
if there is some table of relocatable pointers somewhere, or something
else, I don't know. But clearly for .NET to be able to relocate the
object that a reference refers to, there must be more than just a simple
pointer to that object.

Pete
 
G

Guest

Peter said:
Sorry...I didn't think it was necessary to explicitly state that I was
simply talking about what the .NET documentation uses to describe
references. Of course it uses the word "pointer" elsewhere, just as it
uses all sorts of other words that also do not describe .NET references.

What I mean to say is that if you want to call references pointers, then
it will conflict with pointers, as they are also called pointers.
It is obviously not "just a pointer". Either the compiler, or the .NET
Framework, or both, hide the inner workers from the programmer.

Yes, it's just a pointer.

Actually it's the garbage collector that hides the inner workings. It
uses the type information for the data (the same that is used by
reflection) to recognise the references as references. It's only the
garbage collector that moves objects around, so that's the only place
where references has to be handled differently from pointers.

The compiler only limits what you can do with the reference/pointer, it
doesn't add any extra code for it. Once the code is compiled, it doesn't
care if it's a reference or a pointer. The garbage collector takes care
of everything that has to do with moving objects and updating
references, so the application code never has to worry about that.
But for
the reference to be relocatable, *some* kind of extra work has to be
done. Whether that is for the reference to be a pointer to a pointer,
or if there is some table of relocatable pointers somewhere, or
something else, I don't know.

No, it's just a pointer. The only difference is that the data type is
different. Just as you can have a pointer to a string or a pointer to an
array, you have a reference to a string or a reference to an array. It's
just a pointer that is flagged to be a reference.
But clearly for .NET to be able to
relocate the object that a reference refers to, there must be more than
just a simple pointer to that object.

Nope, there is nothing more. The only difference is the type information
for it. As all variables have type information anyway, there is nothing
extra added.
 
P

Peter Duniho

What I mean to say is that if you want to call references pointers, then
it will conflict with pointers, as they are also called pointers.

I don't want to call references pointers. I don't really see how your
previous reply to my post makes any sense. Maybe you meant to respond to
someone else?
Yes, it's just a pointer.

Obviously, it is not "just a pointer".

Just because the compiler knows it as only a pointer, that does not mean
it's "just a pointer".
Actually it's the garbage collector that hides the inner workings. It
uses the type information for the data (the same that is used by
reflection) to recognise the references as references. It's only the
garbage collector that moves objects around, so that's the only place
where references has to be handled differently from pointers.

In other words, .NET has knowledge of where these references are, and when
an object is relocated, it has to go update those values to reflect the
change in address of the object.

Which is essentially what I wrote (as one possible solution to the
implementation of references) in the post to which you disagreed. The
fact that the compiler isn't doing the work does not change the fact that
the reference is not simply a pointer. It's a special type of memory
address that refers to data in memory that is treated differently from an
actual pointer by the .NET Framework. It's not "just a pointer".
[...]
But clearly for .NET to be able to relocate the object that a reference
refers to, there must be more than just a simple pointer to that object.

Nope, there is nothing more.

Of course there is something more. You went to great lengths to describe
what more there is. Just because the compiler isn't responsible for
handling the "something more", that doesn't mean it's not there. It just
means the compiler doesn't do it.
The only difference is the type information for it. As all variables
have type information anyway, there is nothing extra added.

Of course there is something extra added. The garbage collector moving
things around and updating the references to them is extra.

Pete
 
G

Guest

Peter said:
I don't want to call references pointers. I don't really see how your
previous reply to my post makes any sense. Maybe you meant to respond
to someone else?


Obviously, it is not "just a pointer".

Just because the compiler knows it as only a pointer, that does not mean
it's "just a pointer".

Well, there is nothing more than a pointer there, there is no pointer to
a pointer, or a table of pointers to references. Just the pointer.

In the same way, a pointer is just an integer. The compiler knows that
it can be used to point to a memory location, but it's still just a 32
bit number (on a 32 bit system, of course).
Actually it's the garbage collector that hides the inner workings. It
uses the type information for the data (the same that is used by
reflection) to recognise the references as references. It's only the
garbage collector that moves objects around, so that's the only place
where references has to be handled differently from pointers.

In other words, .NET has knowledge of where these references are, and
when an object is relocated, it has to go update those values to reflect
the change in address of the object.

Which is essentially what I wrote (as one possible solution to the
implementation of references) in the post to which you disagreed. The
fact that the compiler isn't doing the work does not change the fact
that the reference is not simply a pointer. It's a special type of
memory address that refers to data in memory that is treated differently
from an actual pointer by the .NET Framework. It's not "just a pointer".
[...]
But clearly for .NET to be able to relocate the object that a
reference refers to, there must be more than just a simple pointer to
that object.

Nope, there is nothing more.

Of course there is something more. You went to great lengths to
describe what more there is. Just because the compiler isn't
responsible for handling the "something more", that doesn't mean it's
not there. It just means the compiler doesn't do it.
The only difference is the type information for it. As all variables
have type information anyway, there is nothing extra added.

Of course there is something extra added. The garbage collector moving
things around and updating the references to them is extra.

Yes, but that is part of the garbage collector. There is nothing extra
added to the reference.
 
Z

Zytan

No, it's just a pointer.

This would explain why C# is fast. And, if the GC handles the details
(while pasuing the program in the meantime) then the program need know
nothing more than that it is just a pointer.

If it were doubly indirection, then I think we'd see it being slower
than it is.

Zytan
 
Z

Zytan

You're speaking the same thing in two different languages.

To the program, it's just a pointer, like a C++ program sees a
pointer. One level of indirection. When it gets to the 32-bit
number, it knows wherever that points to directly in the data. That's
(one reason) why C# is fast.

But, the GC in C# contains all of the extra crap to handle 'more than
just a pointer' on its end, by moving things around (and updating the
pointers, etc).

Does that suffice as a simple explanation?

Zytan
 

Ask a Question

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

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

Ask a Question

Top