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=-2.9 required=5.0 tests=BAYES_00,MAILING_LIST_MULTI autolearn=unavailable autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,4947e94bd021c540 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2003-10-07 13:40:05 PST Path: archiver1.google.com!news1.google.com!newsfeed.stanford.edu!nntp.cs.ubc.ca!freenix!enst.fr!melchior!cuivre.fr.eu.org!melchior.frmug.org!not-for-mail From: Duncan Sands Newsgroups: comp.lang.ada Subject: Re: C array to Ada pointer to unconstrained array without copying memory Date: Tue, 7 Oct 2003 22:39:54 +0200 Organization: Cuivre, Argent, Or Message-ID: References: NNTP-Posting-Host: lovelace.ada-france.org Mime-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit X-Trace: melchior.cuivre.fr.eu.org 1065559102 1618 80.67.180.195 (7 Oct 2003 20:38:22 GMT) X-Complaints-To: usenet@melchior.cuivre.fr.eu.org NNTP-Posting-Date: Tue, 7 Oct 2003 20:38:22 +0000 (UTC) To: Jeffrey Carter , comp.lang.ada@ada-france.org Return-Path: User-Agent: KMail/1.5.1 In-Reply-To: Content-Disposition: inline X-Virus-Scanned: by amavisd-new-20030616-p5 (Debian) at ada-france.org X-BeenThere: comp.lang.ada@ada-france.org X-Mailman-Version: 2.1.2 Precedence: list List-Id: Gateway to the comp.lang.ada Usenet newsgroup List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Xref: archiver1.google.com comp.lang.ada:400 Date: 2003-10-07T22:39:54+02:00 Hi Jeff, thanks for your reply. > You should also have > > pragma Import (Ada, X); > > to avoid initializing X. But this may not provide usable bounds for X. > If, for example, your compiler stores the bounds in memory just before > the 1st element of X, this may result in garbage for the bounds of X. > > The general technique is to use Ptr as an access value to something as > large or larger than Length can ever be, then immediately take a slice > and pass it elsewhere. Slicing generates the bounds information. The > following compiles: > > procedure Bound_Generation is > type T is new Integer; > > type Real is array (Positive range <>) of T; > subtype Huge is Real (Positive); > > type Huge_Ptr is access all Huge; > pragma Convention (C, Huge_Ptr); > > X_Ptr : Huge_Ptr; > Length : Positive; > > procedure Deal_With_X (X : in Real) is > begin -- Deal_With_X > null; > end Deal_With_X; > begin -- Bound_Generation > -- Get X_Ptr and Length from C > Deal_With_X (X => X_Ptr (1 .. Length) ); > end Bound_Generation; Right. With GNAT there is no problem with the method I mentioned, but this method indeed seems more portable. A few other methods are discussed on the page http://www.adapower.com/lang/accessmem.html > > And then you can make use of X. However being defined on the stack, it > > can be quite awkward to use. It would be nice to have the same thing but > > with X dynamically allocated. For example, > > There is generally no need for a pointer to X; I'd have to know more > about what you're trying to do to understand why you say you want one. I'm a bit surprised you ask. Your comment is analogous to "there is generally no need to use pointers to strings". And indeed, you often don't need them, but there are plenty of legitimate, not to say essential uses for them. I would like to pass a pointer to X all around my program. > With GNAT, you could use 'Unrestricted_Access on X within Deal_With_X to > obtain such a pointer. Woah! Not so! (Or at least so it seems to me). This pointer to X will be a fat pointer, with one part pointing the the data (i.e. X_Ptr) - and this can be used after Deal_With_X returns -, and another part pointing to the bounds. And where are these bounds stored? Right, on the stack (or some other convenient temporary place), and that bit of memory will go away once Deal_With_X returns. So if I use Unrestricted_Access to get a pointer to X and stick it in (for example) a global variable, then accessing X through it after returning from Deal_With_X will lead to swift punishment. > Or, instead of calling a subprogram, you could do > something like: > > declare > type Real_Ptr is access all Real; > > X : Real_Ptr; > > Result : aliased Real := X_Ptr (1 .. Length); > begin > X := Result'Access; > -- Deal with X here > end; But I would like -- Deal with X here (after the end;). And this seems tricky. All the best, Duncan.