.NET Forum / Languages / Managed C++ / January 2005
reference arg
|
|
Thread rating:  |
Ian Lazarus - 04 Jan 2005 00:51 GMT Hello,
If a function arg is a reference to a built in type, is it necessary for the function definition to specify whether the reference is to a managed or un-managed object? If so, does that mean that there needs to be two (otherwise duplicate) functions in order for both types of objects to be processed? E.g.,
void foo(int __gc & x); void foo(int __nogc & x);
Thanks
Tomas Restrepo \(MVP\) - 04 Jan 2005 02:19 GMT Ian,
> If a function arg is a reference to a built in type, is it necessary for the > function definition to specify whether the reference is to a managed or [quoted text clipped - 4 lines] > void foo(int __gc & x); > void foo(int __nogc & x); That depends. You're not talking here about the object being managed/unmanaged, just whether it is being referenced by a tracking pointer (__gc) or a non-tracking pointer (__nogc).
In many cases, it won't be useful to have both overloads; if you're working mostly on the managed side, then the __gc version is preffered because its the one that other languages (like C#) can understand.
 Signature Tomas Restrepo tomasr@mvps.org
Ian Lazarus - 04 Jan 2005 03:25 GMT Thanks but the function in question has no way of knowing whether its arguments will reside on the managed heap or on the stack. It needs to handle both. So what do I do?
Doug Harrison [MVP] - 04 Jan 2005 05:19 GMT >Thanks but the function in question has no way of knowing whether its >arguments will reside on the managed heap or on the stack. It needs to >handle both. So what do I do? You can get away with just the __gc& version, as it can bind to both managed and unmanaged references. As for what you need to do, it appears that overloading doesn't quite work with __gc references as it does with __gc pointers. For instance, the example in the "Managed Extensions for C++ Specification", "7.6 __gc Pointers and Overload Resolution", does not work for references, producing the error below on the f(i) call, i being an unmanaged int:
b.cpp(13) : error C2668: 'f' : ambiguous call to overloaded function b.cpp(6): could be 'void f(int __gc &)' b.cpp(5): or 'void f(int &)' while trying to match the argument list '(int)'
Get rid of the int& overload, and it compiles fine.
 Signature Doug Harrison Microsoft MVP - Visual C++
Ioannis Vranos - 04 Jan 2005 11:21 GMT > Hello, > [quoted text clipped - 6 lines] > void foo(int __gc & x); > void foo(int __nogc & x); If you want to pass a reference of an int (either on the stack or the unmanaged heap), a
void foo(int &x);
would suffice.
If you want to pass an int placed in the managed heap, that is:
int __gc *p = new int(5);
then you may use:
void f(int __gc &x)
However you can always pin the managed object and use the native version:
#using <mscorlib.dll>
void f(int &x) { }
int main() { using namespace System;
int __gc *p = new int(5);
int __pin *pinp = p;
f(*pinp);
// Unpin pinp=0; }
However pinning is considered dangerous for people who do not know what they are doing.
 Signature Ioannis Vranos
Ioannis Vranos - 04 Jan 2005 11:26 GMT > However pinning is considered dangerous for people who do not know what > they are doing. However I just noticed that
#using <mscorlib.dll>
void f(int __gc &x) { }
int main() { int x= 1;
f(x); }
as well as
#using <mscorlib.dll>
void f(int __gc &x) { }
int main() { int __nogc *p= new int(10);
f(*p); }
both compile. So you can do with the managed version for both cases.
 Signature Ioannis Vranos
Ioannis Vranos - 04 Jan 2005 11:32 GMT > However I just noticed that > [quoted text clipped - 27 lines] > > both compile. So you can do with the managed version for both cases. This happens because in .NET int is not an unmanaged type but a *value* type.
 Signature Ioannis Vranos
Doug Harrison [MVP] - 04 Jan 2005 16:06 GMT >> However I just noticed that >> [quoted text clipped - 27 lines] >> >> both compile. So you can do with the managed version for both cases. Is there a significant difference between the two? (The __nogc is redundant, BTW. For that matter, you can't use __gc new to create an int.)
>This happens because in .NET int is not an unmanaged type but a *value* >type. #using <mscorlib.dll>
struct X { };
void f(X __gc&);
void g() { X x; f(x); }
So, I think __gc references (and pointers) can bind to __nogc objects (__value or not) simply because that's the way they're defined.
 Signature Doug Harrison Microsoft MVP - Visual C++
Ian Lazarus - 04 Jan 2005 16:25 GMT What do you mean by "...that's the way they're defined."? My understanding is that __gc indicates to the compiler that the object is located on the "common runtime heap" , i.e., the heap which the garbage collector is managing. A __nogc object, in contrast, is defined to not exist on the common runtime heap, That is my understanding of what the definitions of __gc and __nogc are.
> So, I think __gc references (and pointers) can bind to __nogc objects > (__value or not) simply because that's the way they're defined. Doug Harrison [MVP] - 04 Jan 2005 17:13 GMT >> So, I think __gc references (and pointers) can bind to __nogc objects >> (__value or not) simply because that's the way they're defined. [quoted text clipped - 5 lines] >common runtime heap, That is my understanding of what the definitions of >__gc and __nogc are. MS defined __gc references and pointers to have the ability to bind to __nogc objects (__value or not).
 Signature Doug Harrison Microsoft MVP - Visual C++
Ioannis Vranos - 04 Jan 2005 20:53 GMT > MS defined __gc references and pointers to have the ability to bind to > __nogc objects (__value or not). __gc pointers used like that are probably the so called interior_ptrs of C++/CLI.
In C++/CLI (0.8 draft) they are more restricted to value types only.
 Signature Ioannis Vranos
Doug Harrison [MVP] - 04 Jan 2005 22:12 GMT >__gc pointers used like that are probably the so called interior_ptrs of >C++/CLI. > >In C++/CLI (0.8 draft) they are more restricted to value types only. Whew, I've got the 1.5 draft, and having read 12.3.6 a couple of times, I'm still not sure I understand interior_ptrs. However, according to 12.3.5, tracking references can bind to both gc-lvalues and ordinary lvalues, so the OP's question persists in C++/CLI. I wonder if overloading on tracking works in Whidbey? (I can't test right at this moment.) The analogous overloading doesn't work for references in VC7.1, though it does work for pointers, as I mentioned in my message to the OP.
 Signature Doug Harrison Microsoft MVP - Visual C++
Ioannis Vranos - 04 Jan 2005 23:20 GMT >>__gc pointers used like that are probably the so called interior_ptrs of >>C++/CLI. >> >>In C++/CLI (0.8 draft) they are more restricted to value types only. > > Whew, I've got the 1.5 draft, My mistake, I meant the 1.8 draft:
http://www.plumhall.com/C++-CLI%20draft%201.8.pdf
> and having read 12.3.6 a couple of times, I'm > still not sure I understand interior_ptrs. In simple words (as pin_ptrs) they are handles converted to pointers.
interior_ptrs do not pin though, and their value gets updated when the object is moved.
> However, according to 12.3.5, > tracking references can bind to both gc-lvalues and ordinary lvalues, so the > OP's question persists in C++/CLI. Yes for all objects a % reference works.
> I wonder if overloading on tracking works > in Whidbey? (I can't test right at this moment.) The analogous overloading > doesn't work for references in VC7.1, though it does work for pointers, as I > mentioned in my message to the OP. Well, the code
void f(int %) {}
void f(int &) {}
int main() { int x;
f(x); }
produces:
C:\c>cl /clr temp.cpp Microsoft (R) C/C++ Optimizing Compiler Version 14.00.40904 for Microsoft (R) .NET Framework version 2.00.40607.16 Copyright (C) Microsoft Corporation. All rights reserved.
temp.cpp temp.cpp(11) : error C2668: 'f' : ambiguous call to overloaded function temp.cpp(3): could be 'void f(int &)' temp.cpp(1): or 'void f(int %)' while trying to match the argument list '(int)'
C:\c>
which is quite reasonable.
 Signature Ioannis Vranos
Doug Harrison [MVP] - 04 Jan 2005 23:52 GMT >Well, the code > [quoted text clipped - 25 lines] > >which is quite reasonable. Then it's like VC7.1. However, like I wrote to the OP:
<q> As for what you need to do, it appears that overloading doesn't quite work with __gc references as it does with __gc pointers. For instance, the example in the "Managed Extensions for C++ Specification", "7.6 __gc Pointers and Overload Resolution", does not work for references, producing the error below on the f(i) call, i being an unmanaged int:
b.cpp(13) : error C2668: 'f' : ambiguous call to overloaded function b.cpp(6): could be 'void f(int __gc &)' b.cpp(5): or 'void f(int &)' while trying to match the argument list '(int)'
Get rid of the int& overload, and it compiles fine. </q>
I don't see why it should work for pointers but not for references.
 Signature Doug Harrison Microsoft MVP - Visual C++
Ioannis Vranos - 05 Jan 2005 00:20 GMT > I don't see why it should work for pointers but not for references. Well, since tracking references work for both managed (ref and value) types and unmanaged types, then in the presence of both a tracking reference and a regular one, for an unmanaged type, we have an ambiguity, since both fit.
 Signature Ioannis Vranos
Doug Harrison [MVP] - 05 Jan 2005 01:11 GMT >> I don't see why it should work for pointers but not for references. > >Well, since tracking references work for both managed (ref and value) >types and unmanaged types, then in the presence of both a tracking >reference and a regular one, for an unmanaged type, we have an >ambiguity, since both fit. In the __gc/__nogc world, which is (was? :) the subject of this thread, you can overload pointers on the basis of __gc-ness. You can't do that with references, which is an asymmetry. I don't know if it's intentional or not.
In C++/CLI, tracking references can bind to managed and native objects; see for example:
http://msdn2.microsoft.com/library/hxad2z4x.aspx
But you still can't overload on "tracking" (which in Managed C++, was __gc-ness).
Concerning pointers in C++/CLI, you can overload on interior_ptr and native pointers:
http://msdn2.microsoft.com/library/wzkbta4k.aspx
So the situation is the same in C++/CLI, for the OP's purposes, at least, and so is the asymmetry.
 Signature Doug Harrison Microsoft MVP - Visual C++
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|