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=-0.9 required=5.0 tests=BAYES_00,FORGED_GMAIL_RCVD, FREEMAIL_FROM autolearn=no autolearn_force=no version=3.4.4 X-Google-Thread: 103376,73975695cdfcb86f X-Google-NewGroupId: yes X-Google-Attributes: gida07f3367d7,domainid0,public,usenet X-Google-Language: ENGLISH,UTF8 Received: by 10.68.74.201 with SMTP id w9mr12423045pbv.0.1333526177758; Wed, 04 Apr 2012 00:56:17 -0700 (PDT) Path: r9ni16778pbh.0!nntp.google.com!news1.google.com!goblin1!goblin.stu.neva.ru!eternal-september.org!feeder.eternal-september.org!mx04.eternal-september.org!.POSTED!not-for-mail From: Natasha Kerensikova Newsgroups: comp.lang.ada Subject: Re: Dispatching callback handed over to C Date: Wed, 4 Apr 2012 07:56:16 +0000 (UTC) Organization: A noiseless patient Spider Message-ID: References: <6fb83c74-b2a4-4ae8-9c89-d755b737198f@v22g2000vby.googlegroups.com> <85d1ad51-c02b-44fa-87b6-02aa1d8ba1b2@x17g2000vba.googlegroups.com> Mime-Version: 1.0 Injection-Date: Wed, 4 Apr 2012 07:56:16 +0000 (UTC) Injection-Info: mx04.eternal-september.org; posting-host="Mda950WjNwNLAFOE7yJXQw"; logging-data="1173"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+tZGFim5oJ/T69eeoEdXMI" User-Agent: slrn/0.9.9p1 (FreeBSD) Cancel-Lock: sha1:n7wt689joO4USm6kP5JY+fbAQ3Y= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Date: 2012-04-04T07:56:16+00:00 List-Id: On 2012-04-03, Randy Brukardt wrote: > "Maciej Sobczak" wrote in message > news:85d1ad51-c02b-44fa-87b6-02aa1d8ba1b2@x17g2000vba.googlegroups.com... >> On 3 Kwi, 14:02, Natasha Kerensikova wrote: > ... >>> Actually it uses the assumption that System.Address and void* have the >>> same representation. >>> >>> I wonder how reliable the assumption is. >> >> Whenever Ada and C (or C++) components are linked together, a set of >> "friendly" compilers is needed, so that basic binary compatibility can >> be guaranted - otherwise nothing is going to work at all, not even >> Interfaces.C.int. :-) >> This assumption is pretty safe. > > I disagree. It doesn't work in the current Janus/Ada compiler, for instance. > The basic idea is that System.Address ought to be able to access any memory > on the target that might have hardware located at it. Thus, that address > might need to include segments or equivalent information along with the > "address" itself. Matching the C compiler is irrelevant; we have access > types and convention C for that purpose (and you can't match both of two > possibly different requirements). That was roughly what I was thinking (though not exactly with these words). In my bindings, I'm currently the following types : type Opaque_Data is null record; pragma Convention (C, Opaque_Data); type Opaque_Pointer is access all Opaque_Data; pragma Convention (C, Opaque_Pointer); The library I'm currently binding provides pointers as handles to its internal structures, but even in C the types exposed are incomplete. So I'm using types derived from Opaque_Pointer to deal with them from Ada. It feels to me that Interfaces.C.int is explicitly requesting something that maps correctly to int in C, and that my Opaque_Pointer is explicitly something that maps correctly to C data pointers. While the RM seems to offer no such connection between System.Address and pointers. Now the problem is that I have a solution with System.Address, that works at least on my machine. Despite all my attempts I'm still unable to reach that point with C-convention-ed accesses. > Indeed, using System.Address for any purpose other than interfacing directly > to hardware is Ada 83 thinking, in my view. (Not everyone agrees with this > view.) Using System.Address loses type-safety, Well, considering I'm writing a C binding, there is not much more type safety that can be reached even without System.Address. It even seems I'm fighting type-safety that would have made sense if the subprogram weren't imported, but that is moot since the import itself forsakes any kind of type-safety. > and prevents the compiler > optimizer for working at all (it has to assume the worst about any object in > your program, unless it is willing to completely trash your program). That was another question I had in mind with that mechanism: I'm giving to C a reference to Ada data in one call (namely Event_New) but it gets used later, in another call (to Event_Base_Dispatch) which seeming does not involve the data at all. Should go to some extra steps (but which?) to warn the compiler that my Event object can change during Event_Base_Dispatch call despite that call not involving any Event object? Or maybe just marking the Event object as aliased is enough? > The whole idea of the void pointer is so anti-Ada that it is best to get rid > of it as early as you can. (There is no such thing as "untyped data" in Ada, > and, as Dmitry likes to point out, not in real life, either. There is only > data for which the type is not known at compile-time, and that sort of data > is a problem - best to avoid it.) I feel you are being a bit unfairly harsh towards void pointers here: it looks to me that you are looking at them in a purely Ada context, which is about as incorrect as coding in Ada with another language in mind and complaining about being forced to fight the compiler. In C, void pointer is not really about untyped data, but data whose type is actively treated with agnosticism. Transposed to Ada world, it's like saying it does not make sense to have a record whose components are unknown, and in real life there is no such thing as a record with unknown components. "private" is only about preventing client from depending on component information rather than "void"ing components. > In Claw, we tried to avoid void by simply > defining the interfaces for the types we cared about. For instance, if we > needed to read an array of stream elements, we'd define the API using that > type (rather than void). In other cases, we defined a void type (as access > to something) and used Unchecked_Conversions as needed to make it > crystal-clear this is wildly unsafe. Obviously, you have to do something to > interface to mindless APIs, but you have to hide them as quickly as > possible. That's exactly what I'm trying to do. Void pointers are indeed anti-Ada, because Ada rather uses generic formal types or tagged types or interfaces. The whole art of designing bindings is, in my opinion, to expose an interface as Ada-ish as possible despite the underlying anti-Ada stuff. Still, I cannot avoid void pointer without avoiding writing the binding altogether. Thanks for your insights, Natasha