comp.lang.ada
 help / color / mirror / Atom feed
From: "Randy Brukardt" <randy@rrsoftware.com>
Subject: Re: Interfaces.Shift_Left
Date: Mon, 19 Dec 2011 18:38:53 -0600
Date: 2011-12-19T18:38:53-06:00	[thread overview]
Message-ID: <jcolev$o4n$1@munin.nbi.dk> (raw)
In-Reply-To: 9l71m2FlhuU1@mid.individual.net

"Niklas Holsti" <niklas.holsti@tidorum.invalid> wrote in message 
news:9l71m2FlhuU1@mid.individual.net...
> On 11-12-16 02:23 , Randy Brukardt wrote:
>> "Niklas Holsti"<niklas.holsti@tidorum.invalid>  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.





  reply	other threads:[~2011-12-20  0:38 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-12-12 22:30 Interfaces.Shift_Left awdorrin
2011-12-12 23:34 ` Interfaces.Shift_Left Simon Wright
2011-12-13  1:36   ` Interfaces.Shift_Left Adam Beneschan
2011-12-13 12:00 ` Interfaces.Shift_Left Brian Drummond
2011-12-13 13:15   ` Interfaces.Shift_Left awdorrin
2011-12-13 21:48     ` Interfaces.Shift_Left Randy Brukardt
2011-12-14 18:28       ` Interfaces.Shift_Left awdorrin
2011-12-14 22:49         ` Interfaces.Shift_Left Randy Brukardt
2011-12-15  9:51           ` Interfaces.Shift_Left Niklas Holsti
2011-12-16  0:23             ` Interfaces.Shift_Left Randy Brukardt
2011-12-18 20:47               ` Interfaces.Shift_Left Niklas Holsti
2011-12-20  0:38                 ` Randy Brukardt [this message]
2011-12-20  2:18                   ` Interfaces.Shift_Left Shark8
2011-12-20 10:08                   ` Interfaces.Shift_Left Dmitry A. Kazakov
2011-12-20 19:38                   ` Interfaces.Shift_Left Niklas Holsti
2011-12-20 20:46                     ` Interfaces.Shift_Left Niklas Holsti
2011-12-20 21:13                       ` Interfaces.Shift_Left Simon Wright
2011-12-20 21:08                     ` Interfaces.Shift_Left Simon Wright
2011-12-20 23:26                       ` Interfaces.Shift_Left Randy Brukardt
2011-12-20 23:36                     ` Interfaces.Shift_Left Randy Brukardt
2011-12-21  0:44                       ` Interfaces.Shift_Left Georg Bauhaus
2011-12-21  7:23                       ` Interfaces.Shift_Left AdaMagica
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox