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,b643449bd65c29dc X-Google-Attributes: gid103376,public From: dewar@merv.cs.nyu.edu (Robert Dewar) Subject: Re: Interfacing Ada95 programs to each other and to C and C++ Date: 1998/05/10 Message-ID: X-Deja-AN: 352074937 References: X-Complaints-To: usenet@news.nyu.edu X-Trace: news.nyu.edu 894850200 2693 (None) 128.122.140.58 Organization: New York University Newsgroups: comp.lang.ada Date: 1998-05-10T00:00:00+00:00 List-Id: Joe said: <<1. Alignment clauses do not necessarily govern dynamic objects (those declared in procedures rather than the main). Things that must be aligned must thus be handled at the "main" level, or alignment commands will be ignored. This matters for two reasons. First, many realtime communications systems require specific data alignments. Likewise, I/O drivers and hardware. Second, different compilers, especially if targeted on different processors, often pad the elements of data structures differently. If one makes all fields 32-bit items, padding is lass variable.>> This needs more detail. Certainly if an alignment is specified for a type, this applies to both global and local objects, and indeed to *all* objects of the type, unless specifically overridden (e.g. by a component clause). With the detail above, the most likely suspicion is that this is a compiler problem. Certainly the Ada 95 RM (and GNAT!) guarantees that the alignment of an object of a type always be consistent with the declared alignment. As to the padding, see the discussion of point 3 <<2. Rep specs cannot be used on enumeration types (because many compilers generate tremendous amounts of code to handle all possible cases, however unlikely), so one cannot use enumeration types in messages.>> Again, more details are needed. We know from a previous thread on CLA that one compiler (not GNAT!) mishandled the case where a (completely unnecessary and redundant) rep clause was given confirming the default representation (0,1,2,....) If this is what Joe is referring to, then this is certainly not a language issue, but merely a glitch in a particular compiler (since corrected as far as I know). If we are really talking about a non-default case, then this complaint seems a bit misguided. In Ada 95, there are two ways of mapping an external discrete type that has a small set of non-contiguous values. a) Define an integer type with a set of numeric constants. This corresponds exactly to the C style and semantics, and is usually preferable. b) Define an enumeration type with an enumeration representation clause. This will generate extra code only if operations like pos and rep are used which clearly require this code. I certainly see that programmers might use this feature without realizing the inevitable inefficiencies that result from the use of such types, but this is an error on the part of the programmer. This is a feature that (like any other feature) should only be used if it is needed. I certainly have trouble understanding this as a complaint about Ada 95. If you don't like the (unavoidable) additional code for use of e.g. pos or array subscripting, then don't use the feature! <<3. If an integer field in a record is a subrange type, Ada will tend to use the smallest kind of integer that will hold the field, overriding any rep specs to the contrary. Other languages and compilers, especially on different targets, may chose different kinds of integer and different paddings. This too can be solved by making all integers 32-bit, and dropping any use of subranges (and the attendant range checks).>> What Joe is talking about here is that a record like type x is record a : integer; b : integer range 1 .. 10; c : integer range 1 .. 10; d : integer range 1 .. 10; e : integer range 1 .. 10; end record may be represented differently from struct x { int a; int b; int c; int d; int e; }; since an Ada compiler is free to (but not required to) allocate only one byte for b,c,d,e (or even only 4 bits). In large legacy programs, we have often found assumptions about the layout of such records, and in fact GNAT always allocates the same space for subtypes as for the parent type to minimize disruption in such programs. HOWEVER: this is NOT a complaint about Ada 95, it is a complaint about incompetent Ada programmers. No doubt Joe will complain that only someone with a PhD in computer science could be expected to know, but it is absolutely clear that if you write a record declaration like the above one, you are QUITE EXPLICITLY saying that you do not care how the record is laid out. If you care how a record is layed out, you have two alternatives: 1. Use only types in the record which have a direct correspondence in the interfaced language (e.g. C.Interfaces.int) and then use pragma Convention (C). 2. Use an explicit record representation clause with component clauses that layout the record as required. It sounds like Joe was running into the problem of incorrectly written programs which made unwarranted assumptions about how records are laid out. Portable code does not come automatically, and an incompetent programmer can easily make these kind of bad assumptions, but I don't see it as a legitimate complaint about the language. Joe said that "rep specs" to the contrary were "overridden". I assume he means rep clauses (rep specs is a popular though incorrect term). I am not sure what particular rep clause he is referring to. Certainly the only valid rep clauses for solving this problem are, as described above pragma Convention (actually a rep pragma) or a record representation clause. Note that in the absence of one or other of these two kinds of rep items, a compiler is free even to modify the *order* of the fields in a record, or to store the record in non-contiguous chunks. Often what happens in large programs is that programmers flail around till they get something that happens to work with the particular version of the compiler they are using. This is NOT the way to write portable code. No one is claiming that code in Ada is guaranteed to be portable, and this is especially true of incorrectly written interfacing code. The claim is that Ada 95, uniquely, provides facilities which, if used properly by a competent programmer, can indeed guarantee portable interfacing. interfacing does not come for free, you have to write the program <<4. There may also be a endian problem; we haven't completely sorted this out yet, but we have cases where the wrong end of a 32-bit integer is kept as a packed subrange. This may just be a bug.>> Clearly not much to respond to here. Endian issues should not arise in interfacing between Ada and (e.g.) C on a given machine. <<5. Floating-point fields, 32-bit and 64-bit IEEE 754, have caused no problems so far, even between machines of differing type, something of a surprise. Floating point is more complex than integers, and some machines have somewhat different endian behaviour for floats than for integers.>> Ah! Wait a moment! Absolutely NOTHING in Ada suggests that the problem of interfacing between different machines is solved. And most certainly if you transmit binary fpt data between a big-endian and little-endian machine it certainly will not work. What GNAT does to solve this problem is to provide a version of the stream attribute support that uses XDR, which eliminates problems arising from different representations on different machines. This has nothing to do with interfacing from Ada to other languages. <> I rather suspect that most if not all of the problems referred to above are also the result of human error in not using the features of Ada 95 correctly (or human error in implementing the particular compiler that Joe is using. I am not sure which compiler this is, but from the complaints, I am pretty sure it is not GNAT. In any case, it is important to distinguish between: 1. Fundamental problems in the design of the language 2. Errors in use of the language by programmers 3. Implementation errors in the compiler I certainly do not claim that no errors in categories 2 and 3 exist, but I fail to find any evidence at all in Joe's list that there are any problems in category 1. I believe that Joe's goal of bulletproof portable interfacing with C can indeed be achieved, and have yet to see evidence that this is not the case. Certainly we talk all the time to GNAT customers who have achieved this goal using Ada 95. Robert Dewar