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.3 required=5.0 tests=BAYES_00,INVALID_MSGID autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,c78177ec2e61f4ac X-Google-Attributes: gid103376,public From: dewar@merv.cs.nyu.edu (Robert Dewar) Subject: Re: ada and robots Date: 1997/06/20 Message-ID: #1/1 X-Deja-AN: 251445665 References: <97061611223212@psavax.pwfl.com> Organization: New York University Newsgroups: comp.lang.ada Date: 1997-06-20T00:00:00+00:00 List-Id: Joe said <<"Sort of" is exactly right; neither correct nor consistent from compiler to compiler. Some compilers also provided pragma volatile, but implementations varied, and some were deeply unclear on the concept of volatile, so we couldn't use either shared or volatile. >> pragma Shared is well defined in the Ada 83 standard, and was correctly implemented on all Ada 83 compilers that I have used. I can believe that it is possible that Joe's group chose an ill-suited compiler that did not get this important feature right (I have known plenty of C compilers get things wrong -- and indeed know of one case in which a C compiler got volatile seriously wrong). However, the fact that I know a C compiler that did volatile wrong does not make me say either of (a) C is useless for memory mapped IO (b) the volatile feature in C is useless because it is not implemented right on one compiler. But that appears to be the dubious logic being used in this case for Ada. Actually neither C nor Ada can guarantee to get memory mapped I/O "right" at the language level, since the required semantics are of necessity at the machine language level, and whether or not a given sequence in C or Ada works is definitely bound to be implementation dependent. Yes, usually in Ada (and C), doing the obvious thing works fine, and people often depend on it, but it is a somewhat risky approach. Let me give an example. One customer of ours ported a large code from VADS to GNAT, and it did not work. A huge amount of digging yielded the following "bug" report. type Bits is array (natural range <>) of Boolean; pragma pack (Bits); Bitvar : Bits (0 .. 31); ... Bitvar (17) := 1; Now first, there is no guarantee of the order in which bits in such a packed array are ordered, but there is a natural ordering, which both VADS and GNAT followed (based on the endianness of the machine), so that was not a problem. But the problem was that Bitvar had an address clause for Bitvar use at ... which mapped it into the address space of some custom build hardware. This hardware accepted ONLY word (4-byte) memory requests, and simply malfunctioned in a completely unpredictable manner if byte memory requests were received. You guessed it, VADS used a loadword/or/storeword sequence, and GNAT used a loadbyte/or/storebyte sequence. Now there is nothing to say one of these is better than the other, they simply represent two equally good ways of doing things. The fix turned out to be simple, by changing the code to type Bits is array (0..31) of Boolean; GNAT could be persuaded to generate the word sequence. But there code was always relying in an undocumented way on the particular choice of the compiler, and for that matter, still is. Also, there is nothing really language independent here. Corresponding C code would be equally subject to varying possible compilatoin possibilities. For my taste, I rarely like the idea of using address clauses or the corresponding casts in C for this purpose. I would prefer to write two small inlined routines that used machine language insertions to generate EXACTLY the instructions that the IO hardware requires.