On Sep 4, 2008, at 7:39 AM, Alan W. Irwin wrote:

> On 2008-09-04 00:46-0700 Jerry wrote:
>
>> Can someone try this variation of the mock-example 19 on a 64-bit  
>> machine?I'm very hopeful that the problem is fixed.
>
> First ever success on my 64-bit platform!
>
> [EMAIL PROTECTED]> . compile_and_run.shgcc-4.3 -c x19a_temp.adb
> gcc-4.3 -c type_declaration.ads
> gnatbind -x x19a_temp.ali
> gnatlink x19a_temp.ali plmap.o
>  0.00000000000000E+00
>  1.00000000000000E+00
>  2.00000000000000E+00
>  3.00000000000000E+00
>  4.00000000000000E+00
>  5.00000000000000E+00
>  6.00000000000000E+00
>  7.00000000000000E+00
>  8.00000000000000E+00
>  9.00000000000000E+00
>
> Good work, Jerry, for figuring this out.
>
> I compared with the old code that didn't work, but did not  
> understand the
> differences.  Could you explain for those of us who do not  
> understand Ada
> that well?  What was unique about the bindings exercised by example  
> 19?  Or
> is this a general 64-bit issue which requires a number of changes  
> to the
> bindings to fix?
>
> Alan
>
I' really glad to hear that the example works. I'll give full credit  
to the gurus at comp.lang.ada--all I had to do was to try to  
understand enough of their arcane explanations and speculations to  
put in the correct repair.

The situation with Example 19 is unique within the PLplot world. The  
callback there is somewhat different in its structure from other  
callbacks in PLplot.

Ada arrays carry with them information other than what is stored in  
the array proper. This includes the first index and last index  
(arrays don't have to begin with index 0--one of my gripes about many  
languages), the length, and the range. These are somewhat redundant  
but convenient in different situations. Say an array A is indexed  
from 3 to 7. Then A'First is 3, A'Last is 7, A'Length is 5, and  
A'Range is kind of like an enumeration and evaluates to 3 .. 7  
where .. is a reserved word (I suppose).

(Diversion: This makes writing loops in Ada a snap -- for i in  
A'Range loop bla bla bla end loop;. If the range changes, there is no  
need to re-write the loop. Plus, the loop index can be any enumerated  
type or subtype, so something like for Day_Of_Week in Monday ..  
Friday bla bla end loop; is fine. The loop variable is always locally  
defined and goes out of scope when the loop exits--no possibility of  
(mis)using loop variables in other places.)

There are two ways to declare arrays in Ada--constrained arrays and  
unconstrained arrays. Constrained arrays have their attributes set in  
the declaration which might be 1 .. 31 for something related to days  
of the month. But there is often the need to have (subprograms that  
process) arrays with particular element types but with unknown (or  
variable) start and end indices. These array types can be declared  
with an open range (unconstrained array) but with a particular case  
taking on a particular range. Normally, Ada programs accept any  
(actual) version of the unconstrained array as a parameter as long as  
it has valid indices (attributes) and element type. The attributes  
come along for the ride as part of the actual parameter.

The situation in Example 19 is that the calling chain (more or less)  
is Ada calling e.g. plmap which is in C and then plmap (or some  
other, deeper, C subprogram) calling the Ada program mapform19. The  
problem comes when the C subprogram calls the Ada mapform19--in the  
earlier simple example, for example, there is no way for it to tell  
mapform19 what x'First is when the formal parameter for x is an  
unconstrained array. The speculation from the guru list is that Ada  
_thinks_ it knows where x'First is stored and reads a value from that  
location. The read value is garbage but Ada proceeds anyway and is  
soon writing into the wrong place. The speculation is that the reason  
that it works on some machines and not others is that random memory  
locations frequently contain the value zero which is exactly the  
offset needed to make the calculation work correctly; if it is not  
zero, all bets are off. There was no speculation as to why 32-bit  
systems seem to work and 64-bit systems don't.

There are other situations in the bindings which are similar to this  
but which do not contain all of the elements of Example 19. For  
example, in many places, Ada calls (or binds directly to) C or at  
least passes information to C. This is fine and actually part of the  
Ada language--the Ada argument list is simply made to match what C  
expects, typically with foo(x'Length, x). There are also places where  
in a callback C calls Ada but without passing an unconstrained array.  
I think that happens in e.g. plcont. It's the combination of passing  
an unconstrained array from C to Ada that causes trouble.

The repair is straightforward if inelegant and possibly prone to  
cause aggravation to the occasional user. (In looking at the Ada  
code, remember that access types are like pointers.) I simply  
replaced the unconstrained array (type Real_Vector in the simple  
example) with a constrained array (subtype Constrained_Real_Vector)  
which is indexed from 0 to 20. I know that this size is adequate  
because I know that mapform19 requires only an array of size 10, as  
called from plmap--11 elements are wasted. This repair works because  
there is a known amount of memory allocated for x (21 elements) and  
the first index is 0 which is what C expects.

In the actual PLplot code, I've hardwired the corresponding array  
subtype to have a range of 0 .. 2000. It is impossible for someone to  
compile a mapform-like function that uses malformed arrays x and y  
(just because that's the way Ada is) but they will be frustrated if  
they need to have more than 2001 elements in those arrays. (I'm open  
to suggestions for some number other than 2001.)

There was some surprise on comp.lang.ada that this example even  
compiled. But the official Ada documentation (as read by some on that  
list) specifically says that passing unconstrained arrays to foreign  
languages is not necessarily supported.

Hope that helps--probably more info than you wanted.

I've submitted these changes to SVN so I hope to hear more good news.

Jerry

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Plplot-devel mailing list
Plplot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/plplot-devel

Reply via email to