Re: What's with the new C++/CLI pointers (handles ^)? Managed C++.NET

Tech Tip: Click here to run a free scan for Windows Errors and optimize PC performance





On 19 déc, 12:10, "raylopez99" <raylope...@xxxxxxxxx> wrote:
microsoft.public.dotnet.languages.vc

See comments inline

///////////////////////////////////////////////////////////////
// in managed C++/CLI console mode, using Visual Studio 2005, C++.NET

int intVT = 10;
int %intRef = intVT;
Here we have a tracking reference that is "pointing" to a local
variable (on the stack)

int ^y = gcnew int(200);
Console::WriteLine("Should be 200 {0} EITHER WAY !: {1} ", y, *y);

When passing y to WriteLine, you are passing a handle to an object that
is on the garbage-collected heap (an Int32^). Since Int32 implements
IFormattable, WriteLine will call IFormattable::ToString on this
object.
When passing *y to WriteLine, you are implcitely unboxing the object,
and therefore passing an int to WriteLine, who knows how to handle it.


*y = 210; //also works y = 210; //WHY y, *y same?
y=210 works because there will be no meaning in changing the value of a
handle (remember, in .NET, handles are OPAQUES : there is no way to
assign them directly a value as you can do with pointers). In that
case, the compiler chooses the alternate interpretation instead of
spiting an error. I would say this choice is debatable, but this is how
things are....


Console::WriteLine("Should be 210 {0}...is it? (Yes!)",*y);

y = intRef;
Here is the danger! Since y is an Int32^, it can only "points" to
object on the managed heap. This line implicitely boxes the intRef
value : An In32 is gcnew-ed on the the managed heap and is assigned the
intRef value. This is a COPY of the original value. See "Implicit
boxing" in MSDN for more details.


Console::WriteLine("Should be intRef or 10: {0}...is it? (Yes!)",y);
See my explanation concerning the first WriteLine call....


intRef = 21;
Console::WriteLine("Should be intRef or 21: {0} , {1}...is it? (NO!)",y, intRef); //WHY NOT?
See above : y points to a COPY of intRef.


y = intRef; //but now it should work: add-- y = intRef; // also works:

Here again, since "y" has no possible meaning, the compiler interprets
it as "µy" (which I feel is dubious)

*y = intRef; // same answer of 21! //Why same answer (why y, *y same)?

Console::WriteLine("Should be intRef or 21: {0} , {1}...is it?> (Yes!)",y, intRef);

//y = &intVT; //unsafe operation by definition? (NO, illegal! Won't compile!)
//Why won't compile?

A handle must "point" to an object on the garbage-collected heap, so
it can't be assigned the address of a stack object.

Arnaud
MVP - VC

.