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-Thread: 103376,c5f68ab74d5099ee X-Google-NewGroupId: yes X-Google-Attributes: gida07f3367d7,domainid0,public,usenet X-Google-Language: ENGLISH,ASCII-7-bit Received: by 10.68.74.201 with SMTP id w9mr129439pbv.0.1324341536534; Mon, 19 Dec 2011 16:38:56 -0800 (PST) MIME-Version: 1.0 Path: lh20ni42260pbb.0!nntp.google.com!news2.google.com!goblin2!goblin1!goblin.stu.neva.ru!news.tornevall.net!news.jacob-sparre.dk!pnx.dk!jacob-sparre.dk!ada-dk.org!.POSTED!not-for-mail From: "Randy Brukardt" Newsgroups: comp.lang.ada Subject: Re: Interfaces.Shift_Left Date: Mon, 19 Dec 2011 18:38:53 -0600 Organization: Jacob Sparre Andersen Research & Innovation Message-ID: References: <18214312-82f5-45c4-b20d-cb530b500929@h3g2000yqa.googlegroups.com> <5f989095-5c1c-4b23-a538-d70f4718b4b1@l19g2000yqc.googlegroups.com> <9ktu5mFn31U1@mid.individual.net> <9l71m2FlhuU1@mid.individual.net> NNTP-Posting-Host: static-69-95-181-76.mad.choiceone.net X-Trace: munin.nbi.dk 1324341535 24727 69.95.181.76 (20 Dec 2011 00:38:55 GMT) X-Complaints-To: news@jacob-sparre.dk NNTP-Posting-Date: Tue, 20 Dec 2011 00:38:55 +0000 (UTC) X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2900.5931 X-RFC2646: Format=Flowed; Response X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.6157 Date: 2011-12-19T18:38:53-06:00 List-Id: "Niklas Holsti" wrote in message news:9l71m2FlhuU1@mid.individual.net... > On 11-12-16 02:23 , Randy Brukardt wrote: >> "Niklas Holsti" wrote in message >> news:9ktu5mFn31U1@mid.individual.net... >>> On 11-12-15 00:49 , Randy Brukardt wrote: ... >>>> Right. This definitely should be done using record representation >>>> clauses >>>> if >>>> there is a choice. >>> >>> I'm sorry to say that I disagree, and now always use the shift-and-mask >>> method. >> >> Might as well write in C then, this sort of code is complete, >> unmaintainable >> junk. > > Ooh, harsh words. I'm trying not to take offence. Sorry, that wasn't really aimed at you. Your application (which has to process many foreign machine formats) is highly unusual, and I would not want most readers to take away the same "lesson" you learned, because it is wrong in general. But I realize that given the architecture of your system, having a "dirty" routine doing the conversion into the internal format might very well be the best solution. It's rarely possible to make that sort of code "pretty" because it has performance impliciations or just plain messy formats in the foreign systems. ... > Of course I hide the implementation in an "extract field" function with > the bit numbers as parameters. My code typically decodes machine > instructions from the instruction set of some processor; the user manual > of that processor is the specification for my SW; the user manual normally > shows the format of a given instruction by a figure of the instruction > with the fields indicated by bit numbers; there is an immediate > correspondence between this figure and the calls of the "extract field" > functions. Very easy to write, check, and maintain, in my experience. I wouldn't use an "extract field" function in my own code simply because Janus/Ada does not do inlining of subprograms. Thus the performance hit of such a function would be severe (it was a factor of 3 for code generation, I recall.) And thus in my code, this turned into a bunch of multiplies and divides, along with a nice ascii version of the diagram from the processor manual. It surely would have been better to put the diagram directly in the Ada code (we didn't have record rep. clauses in the early days of Janus/Ada, or I surely would have done so). The advantage, of course, is that the instruction description is only in the text once (as a record type declaration, which is quite readable), rather than twice (bit extracts in whatever form, plus some documentation of what they mean). >>> I used to be charmed by record representation clauses, until I wanted to >>> write Ada 95 code that was portable between machines with different bit >>> numbering orders. >> >> It's true, that's a problem. Luckily, it's not a real problem in practice >> for the vast majority of users, since pretty much all popular machines >> these >> days use the same bit numbering. > > "All the world is a VAX -- no, an Intel -- no, an Xxx", eh? Not at all. My understanding is that virtually all recent processors are little-endian (and all of the new processors in common use). I believe this is driven in part by the need of all machines to interoperate (unlike the little islands of the 1960s and 1970s). So I don't think we'll be seeing many new host machines using big-endian numbers (there are a few legacy systems still around, of course), especially as there is no real advantage of one system over the other. In a sense, this is similar to the 1's complement - 2's complement divide. If you have code that only works on 2's complement machines, it really doesn't matter anymore, but once upon a time, that would have been a big deal. I think we're seeing the same sort of thing with bit numbering and byte ordering (BTW, these two things are linked together, it's not sensible to swap only one and not the other -- otherwise your integer fields get broken into chunks). So it is not that big of a deal to use one system and ignore the other. Unless, of course, you are doing processing on/for one of those legacy systems (which seems to be in part your situation, again, your situation seems unusual to me). > I do not want to write programs that have such an implementation > dependency. I wouldn't go so far as to call such code "junk", but it would > be as bad as assuming that Integer is 32 bits. As I said above, I think it is more like assuming your machine is 2's complement. Not that big of a deal, but it matters if you need absolute portability. .... >>> Another factor in this decision is that in my applications, the raw data >>> (machine instructions for various processors) can actually have several >>> different structures (instruction formats), so an approach using record >>> representation clauses needs as many different record types and >>> unchecked >>> conversions from the raw data (bit-strings or words) to the appropriate >>> record type. The operational approach entirely avoids these conversions. >> >> Of course, the vast majority of Unchecked_Conversions generate no code at >> all, so these conversions have no run-time impact > > Sure, run-time is no problem; the problem is having to write a lot of type > declarations, plus their representation clauses. There's just much more > text, more type names, more component names, which to me have little > benefit. Each of these types and components would be used only once, in > the Ada code that translates an instruction of that format into my > internal representation. I view these declarations as a good stand-in for the documentation (comments) that I'd otherwise have to write. They're a lot more readable than shifts or multiplies! >> and IMHO they're still >> more readable than a bunch of shifts or multiplies. > > I agree, if the shifts and masks would be written in-line, which I don't > do. I write calls to my "extract field" function instead, which I find > very readable and easy to compare to the specification. Obviously, your mileage varies from mine. I presume you're not documenting "the specification" in the code, because otherwise you would have to write it twice (which would make the record types a lot more attactive). I wouldn't allow that in my code (I'm not going to make the reader go fumble with books or PDFs to understand the layout!), but of course YMMV. [Your extract operation will define the bits involved, but not the meaning, and I presume how you use the result will help explain the internal meaning, but not the original definition.] Anyway, let me repeat again: YMMV. Your application works for you, and that's fine. I just don't think that you should tell the world (most of whose applications are very different from yours) that record represenation clauses don't work. Because they're in the top 5 reasons to use Ada, and without them, Ada becomes just another programming language (with better syntax, but good luck convincing anyone of that). Randy.