<html>
<head>
<style><!--
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 12pt;
font-family:Calibri
}
--></style></head>
<body class='hmmessage'><div dir='ltr'>I'm struck by:<br><br><pre>"The values allowed for n are implementation-dependent. An illegal<br>value for n is a static error. The legality of a packed type can<br>depend on its context; for example, an implementation could prohibit<br>packed integers from spanning word boundaries."<br><br>Stuff is left up to the implementation, not the language definition.<br><br><br> - Jay<br></pre><br><br><div><div id="SkyDrivePlaceholder"></div>> From: dragisha@m3w.org<br>> Date: Sun, 2 Sep 2012 16:45:54 +0200<br>> To: rodney_bates@lcwb.coop<br>> CC: m3devel@elegosoft.com<br>> Subject: Re: [M3devel] Bitfields and endianness<br>> <br>> Rodney put it as clear as possible. We already have packing and alignment issues dictated by language definition. What we need is to make sense out of packing, fix endiannes and pack left to right. Period.<br>> <br>> <br>> On Sep 2, 2012, at 4:41 PM, Rodney M. Bates wrote:<br>> <br>> > Pardon me for showing my frustration, but I think it is about<br>> > time to consider what the *language* says about bit fields.<br>> > <br>> > The language says:<br>> > -------------------------------------------------------------------------<br>> > A declaration of a packed type has the form:<br>> > <br>> >    TYPE T = BITS n FOR Base<br>> > <br>> > where Base is a type and n is an integer-valued constant<br>> > expression. The values of type T are the same as the values of type<br>> > Base, but variables of type T that occur in records, objects, or<br>> > arrays will occupy exactly n bits and be packed adjacent to the<br>> > preceding field or element. For example, a variable of type<br>> > <br>> >    ARRAY [0..255] OF BITS 1 FOR BOOLEAN<br>> > <br>> > is an array of 256 booleans, each of which occupies one bit of storage.<br>> > <br>> > The values allowed for n are implementation-dependent. An illegal<br>> > value for n is a static error. The legality of a packed type can<br>> > depend on its context; for example, an implementation could prohibit<br>> > packed integers from spanning word boundaries.<br>> > -------------------------------------------------------------------------<br>> > <br>> > First off, the last paragraph clearly says that a compiler cannot just<br>> > silently violate the layout rules given above.  If it places<br>> > restrictions, it has to refuse with an error message.<br>> > <br>> > Everyone is aware of "will occupy exactly n bits", but I have lost<br>> > count of the number of times I see posts that imply the writer has<br>> > missed "packed adjacent to the preceding field or element".  This<br>> > means there can be no padding added by the compiler, neither for<br>> > alignment nor any other reason.  With this rule, size, alignment, and<br>> > padding can be completely controlled by the programmer.<br>> > <br>> > Note that there are no other rules about record/object layout, so a<br>> > compiler is free to reorder them if none have a packed type.  This is<br>> > not actually happening in our compiler.  If there is a mix, a group<br>> > consisting of one non-packed field and all its immediately following<br>> > packed fields would have to be kept together, but different groups<br>> > could be reordered.  So if you only want to avoid extra padding to<br>> > save space or something, mixed packed/nonpacked fields might be<br>> > useful, but for full layout control to match some external software or<br>> > standard, you really would want to make them all packed.<br>> > <br>> > That leaves endianness, which the language says nothing about, that I<br>> > can find.  Apparently, the compiler(s) lay out packed fields in the<br>> > endianness of the target machine.<br>> > <br>> > Which raises a big pet peeve of mine.  Big-endian is fine, but<br>> > so-called little-endian is an inconsistent system.  It numbers bits<br>> > and bytes right-to-left only within a field.  Between fields (and<br>> > array elements), it is still left-to-right.  Ditto for input and<br>> > output, which is always left-to-right by bytes, regardless of the size<br>> > of contained fields, which i/o software and hardware would have no way<br>> > of knowing about anyway.  Ditto for instruction stream readout.  (Ever<br>> > try to figure out how to write a consistent memory dump for a<br>> > little-endian machine?  Mercifully, we don't much use them anymore,<br>> > but there was a time.)<br>> > <br>> > The compiler lays out in increasing bit numbers, which get reduced<br>> > later (in little-endian) to bytes via right-to-left ordering of bits<br>> > within bytes and also multiple byte-fragments of a single field.<br>> > <br>> > The result is that you cannot in general, use one set of endian rules<br>> > to duplicate the way things would be done in the other.  Dragiša's<br>> > original example shows this clearly.  The standard he is trying to<br>> > match lays things out in big-endian.  In a little-endian<br>> > reinterpretation of this layout, some fields have fragments that are<br>> > discontiguous, as well as out of sequence.<br>> > <br>> > So to use a little-endian version of Modula-3's packing rules (as the<br>> > compiler is doing, since it is compiling for a little-endian target),<br>> > he would have to do his own bit-twiddling of the fragments to get a<br>> > field in or out of the record.  Which pretty well defeats the purpose<br>> > of having a packed record layout.  It would be more-or-less as easy,<br>> > and probably a lot clearer to just treat as ARRAY OF Word.T or such<br>> > and bit twiddle on that.<br>> > <br>> > I think the clear conclusion is that the language's system is<br>> > incomplete, and to fix it, we need a way to specify the endianness<br>> > used to lay out a record/object with packed fields (and arrays too)<br>> > independent of that of the target machine.  Whether that is a pragma<br>> > or in the core of the language is a secondary question, although I<br>> > prefer a true language syntax, just because pragmas, in theory, are<br>> > not supposed to change the behavioral semantics of a program.<br>> > <br>> > We also need to specify in the language, what the actual rules are for<br>> > little-endian, where it is far from obvious, due to its<br>> > endian-confusedness.<br>> > <br>> > <br>> <br></div>                                    </div></body>
</html>