From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,1e36228aae0595da X-Google-Attributes: gid103376,domainid0,public,usenet X-Google-Language: ENGLISH,ASCII Path: g2news1.google.com!news1.google.com!postnews.google.com!p10g2000prf.googlegroups.com!not-for-mail From: Adam Beneschan Newsgroups: comp.lang.ada Subject: Re: Access to function returning class-wide type Date: Thu, 21 Aug 2008 10:02:58 -0700 (PDT) Organization: http://groups.google.com Message-ID: References: NNTP-Posting-Host: 66.126.103.122 Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-2 Content-Transfer-Encoding: quoted-printable X-Trace: posting.google.com 1219338178 10672 127.0.0.1 (21 Aug 2008 17:02:58 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: Thu, 21 Aug 2008 17:02:58 +0000 (UTC) Complaints-To: groups-abuse@google.com Injection-Info: p10g2000prf.googlegroups.com; posting-host=66.126.103.122; posting-account=duW0ogkAAABjRdnxgLGXDfna0Gc6XqmQ User-Agent: G2/1.0 X-HTTP-UserAgent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.7.12) Gecko/20050922 Fedora/1.7.12-1.3.1,gzip(gfe),gzip(gfe) Xref: g2news1.google.com comp.lang.ada:1736 Date: 2008-08-21T10:02:58-07:00 List-Id: On Aug 21, 3:13 am, Pawe=B3 'Nivertius' P=B3azie=F1ski wrote: > Hello all. > > I'm new here, but I'll try to stick on. > > Let me start with a tricky problem: > > Consider following code: > > ---------------------------------------- > > package A is > type Abstracted is abstract tagged null record; > function Proc (N : Natural) return Abstracted is abstract; > > type The_Access_Type is access function (N : Natural) return > Abstracted'Class; > > end A; > > -- package A body ommited; > > with A; > package B is > type Derived is new A.Abstracted with null record; > function Proc (N : Natural) return Derived; > > Failing_Object : A.The_Access_Type :=3D B.Proc'Access; > -- will not compile, error: 'expected type The_Access_Type / fou= nd type > access function Proc defined at ...' > > function Proc_Wrapper (N : Natural) return Abstracted'Class; > > Working_Object : A.The_Access_Type :=3D B.Proc_Wrapper'Access; > -- compiler doesn't complain > > end B; > > package B body is > function Proc_Wrapper (N : Natural) return Abstracted'Class is > begin > return Abstracted'Class'(Proc (N)); > end Proc; > > -- function Proc body ommited > end B; > > ---------------------------------------- > > What I need is a access type to 'constructor' of an derivate of abstract > object. > As I presented, there is a workaround, but that's not the 'right' way to = do > it. I really want to do it without some tricky wrapping. > How do I define The_Access_Type to do what I want? Others have posted discussions of how to accomplish what you want, or what we think you might want, using a different construct. I just wanted to point out that, from a low-level standpoint, there's no way to have an access type that could refer to *both* a function that returns Abstracted'Class *and* a function that returns the specific type Derived. The reason is that an access-to-function is basically just going to hold the address of the function (and some other information). A function that returns T'Class can't work the same as a function that returns a specific type, because the function that returns T'Class won't know in advance how big the return object is going to be, so some dynamic heap (or "secondary stack") allocation must be involved. A function that returns Derived, though, knows how big the return object is, so the result can be pre-allocated. This means that both the function and the function's caller have to adopt different mechanisms for passing the return object between them. If you have an access-to-function which could point to either one, the code that makes a call through this access-to-function pointer isn't going to know which return object mechanism would be used, so the result would be a mess. If Ada were to provide a mechanism so that B.Proc'Access could be used, the compiler would have to generate its own wrapper, same as you're doing. This isn't necessarily a bad thing; there are already other cases where Ada compilers have to generate wrappers (at least ours does). But I think it's useful to understand the underlying mechanisms involved, to get a better understanding of why the language won't let you do certain things. By the way, if you decide that the other suggestions don't work and you need to write a wrapper anyway, you shouldn't have to rewrite the whole wrapper for every type; I think you can use a generic to make the process of declaring the wrapper a lot simpler. -- Adam