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-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,4947e94bd021c540 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2003-10-10 09:45:00 PST Path: archiver1.google.com!news2.google.com!news.maxwell.syr.edu!feed.news.nacamar.de!newsfeed.freenet.de!194.168.4.91.MISMATCH!newspeer1-gui.server.ntli.net!ntli.net!newsfep1-gui.server.ntli.net.POSTED!53ab2750!not-for-mail From: "Steve Adams" Newsgroups: comp.lang.ada References: Subject: Re: C array to Ada pointer to unconstrained array withoutcopyingmemory X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2800.1158 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165 X-Inktomi-Trace: cpc1-fare1-3-0-cust50.cos2.cable.ntl.com 1065804291 610 81.96.32.50 (10 Oct 2003 16:44:51 GMT) Message-ID: <8mBhb.549$Cw3.178@newsfep1-gui.server.ntli.net> Date: Fri, 10 Oct 2003 17:44:49 +0100 NNTP-Posting-Host: 80.1.224.4 X-Complaints-To: abuse@ntlworld.com X-Trace: newsfep1-gui.server.ntli.net 1065804292 80.1.224.4 (Fri, 10 Oct 2003 17:44:52 BST) NNTP-Posting-Date: Fri, 10 Oct 2003 17:44:52 BST Organization: ntl News Service Xref: archiver1.google.com comp.lang.ada:618 Date: 2003-10-10T17:44:49+01:00 List-Id: "Duncan Sands" wrote in message news:mailman.57.1065769242.25614.comp.lang.ada@ada-france.org... > > Freeing a fat pointer with unchecked_deallocation is a good question, I > > would guess that it does free correctly. However its any ones guess outside > > of Gnat whether the data is freed in one call or as two. If two I am in > > trouble :) > > > > However, every time i traced the use of these things the bounds were ALWAYS > > immediately before the data in memory, suggesting a single allocation from > > the heap. > > Yes, it seems like an obvious optimization: arrays allocated on the heap can have > no address clause, so you can put the bounds with the data if you like, and reduce > the number of memory allocations. Also, if the bounds are immediately before the > data, doesn't that prove that it was done in one memory allocation, since (IIRC) > malloc reserves some bytes for itself just before a block of memory it allocates, and > GNAT uses malloc? > > Ciao, > > Duncan. > As you say, it makes sense to allocate the bounds & data in a single call, I'm not sure if it also fits that 'access for an unbounded array type is supposed to return a reference to the first element, this might be a Gnatism rather than an LRM statement. Good luck on the use of this, if you find out how Gnat lays out the bounds for a 2D array, please let me know, it might be a useful piece of knowledge, my guess is that it will be [x low bound][x up bound][y low bound][y up bound] As that keeps making sense no matter how far you scale it for dimensions. Bear in mind that Gnat may change the layout of these things, so it's worth writing a piece of test code to print memory around unbound arrays in C that you can call. Then should Gnat release a new version, you can run this and feel happy that the memory layout is still the same. A really quick example of this might be: -- Ada procedure check_d_a is type i_arr is array (positive range <>) of integer; type i_arr_ptr_thin is access i_arr; for i_arr_ptr_thin'size use 32; -- machine dependant procedure C_Mem(the_array : in out i_arr_ptr_thin; lbound, ubound : integer); pragma import(C,C_Mem, "_c_mem"); -- need to look at your linker ia : i_arr_ptr_thin := NULL; begin ia := new i_arr(99..101); -- easy to look for values for i in ia'first .. ia'last loop ia(i) := i-99+2002; -- again, easy to look for values, consider using hex, that way you can look for easy 'strings' end loop; c_mem(ia,ia'fist,ia'last); end check_d_a; // C #define MEM_OFFSET 20 extern "C" void c_mem(int *arr,int l, int h) { printf("BOUNDS: %d .. %d\n",l,h); int sz = (h - l)+1; int *cparr = arr - MEM_OFFSET; // work 20 ints before data for(int i=0; i < sz + MEM_OFFSET; i++) { printf("OFFSET:%d\tMEM location 0x%08X\tVAL%d\n",i-MEM_OFFSET,cparr,*cparr); cparr++; } } All written without checking, so there will be a bug or two. You should then see something like: OFFSET:-20 Mem location:0xE0F00FF0A1 VAL:-848484776 .. OFFSET:-2 Mem Location:0xE0F00F1F3 VAL:99 OFFSET:-1 Mem Location:0xE0F00F1F4 VAL:101 OFFSET:0 Mem Location:0xE0F00F1F5 VAL:2002