<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://community.arm.com/utility/feedstylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>incorrect behavior with [somewhat] complex struct...</title><link>https://community.arm.com/developer/tools-software/tools/f/keil-forum/24356/incorrect-behavior-with-somewhat-complex-struct</link><description> 
I have a somewhat complex structure in my C code, and driver
functions to read or write data with it. 

 
The simpler parts of the struct (such as ioflags2 below) and their
driver functions work just fine. However, the more complex parts of
the struct</description><dc:language>en-US</dc:language><generator>Telligent Community 10</generator><item><title>RE: incorrect behavior with [somewhat] complex struct...</title><link>https://community.arm.com/thread/153530?ContentTypeID=1</link><pubDate>Mon, 03 Aug 2009 03:01:43 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:a2bdcb78-10be-4b94-b537-1ed3c33b1efd</guid><dc:creator>Ashley Madison</dc:creator><description>&lt;p&gt;&lt;p&gt;
&amp;quot;I would still like to see a self contained minimal example, and
preferably an example of a device (ideally ARM based) which exibits
the difference behavior that you are trying to show. And I am not
talking about a handful of perhaps redundant instructions, but code
that actually&lt;br /&gt;
behaves incorrectly.&amp;quot;&lt;/p&gt;

&lt;p&gt;
you will find, as many others have, that Per is an expert on
irrelevancy and s/he will talk about anything but.&lt;/p&gt;

&lt;p&gt;
Put my words down: Per will NOT produce such an example in the
next 10 posts of his.&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: incorrect behavior with [somewhat] complex struct...</title><link>https://community.arm.com/thread/152866?ContentTypeID=1</link><pubDate>Mon, 03 Aug 2009 00:56:39 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:abf94025-b424-46c4-9a85-4e462bd6d686</guid><dc:creator>Marcus Harnisch</dc:creator><description>&lt;p&gt;&lt;p&gt;
&amp;gt; The problem example in my first post was for a processor
that&lt;br /&gt;
&amp;gt; auto-acknowledges status bits as they are read. That means that
the&lt;br /&gt;
&amp;gt; software must do one (1) read and then process all bits.&lt;/p&gt;

&lt;p&gt;
I think I got that part.&lt;/p&gt;

&lt;p&gt;
&amp;gt; The solution to that (if we ignore other problems with bit
fields) is&lt;br /&gt;
&amp;gt; to copy the register value once to a union of an unsigned and
the bit&lt;br /&gt;
&amp;gt; fields and write:&lt;/p&gt;

&lt;p&gt;
Sure, as I said. But the requirement of having to read the
register&lt;br /&gt;
just once in this case is not specific to bit fields, is it.&lt;/p&gt;

&lt;p&gt;
&amp;gt; Alas, I managed to **** up the example of the old-style&lt;br /&gt;
&amp;gt; solution. There shouldn&amp;#39;t have been any |= in the assign, but
just an&lt;br /&gt;
&amp;gt; assign. Sorry for the confusion.&lt;/p&gt;

&lt;p&gt;
No problem, but to be sure that we are on the same page I would
still&lt;br /&gt;
like to see a self contained minimal example, and preferably an&lt;br /&gt;
example of a device (ideally ARM based) which exibits the
difference&lt;br /&gt;
behavior that you are trying to show. And I am not talking about
a&lt;br /&gt;
handful of perhaps redundant instructions, but code that actually&lt;br /&gt;
behaves incorrectly.&lt;/p&gt;

&lt;p&gt;
&amp;gt; But when leaving the ARM world, it isn&amp;#39;t even known if the
bits will&lt;br /&gt;
&amp;gt; be allocated low-to-high or high-to-low, so switching between
two&lt;br /&gt;
&amp;gt; different compilers but staying with the same processor can&lt;br /&gt;
&amp;gt; completely break everything.&lt;/p&gt;

&lt;p&gt;
Possibly. It all depends on what degree of protability I need. I
don&amp;#39;t&lt;br /&gt;
expect to find e.g. ARMv6/v7 page table descriptors in other&lt;br /&gt;
architectures. It is perhaps a choice whether I prefer using the&lt;br /&gt;
&amp;quot;traditional&amp;quot; approach with macros/enums/bit-ops &lt;i&gt;everywhere&lt;/i&gt;
or&lt;br /&gt;
whether I would rather have an architecture specific header file
with&lt;br /&gt;
appropriate bit-field definitions.&lt;/p&gt;

&lt;p&gt;
I don&amp;#39;t claim that bit fields are always the better approach, but
it&lt;br /&gt;
seems that many people show some knee-jerk reactions against bit&lt;br /&gt;
fields wherever the question comes up.&lt;/p&gt;

&lt;p&gt;
There are valid arguments &lt;i&gt;against&lt;/i&gt; using bit fields in
certain&lt;br /&gt;
situations. But most arguments thrown out by people can be
disproved&lt;br /&gt;
easily.&lt;/p&gt;

&lt;p&gt;
Regards&lt;br /&gt;
Marcus&lt;br /&gt;
&lt;a href="http://www.doulos.com/arm/"&gt;http://www.doulos.com/arm/&lt;/a&gt;&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: incorrect behavior with [somewhat] complex struct...</title><link>https://community.arm.com/thread/152072?ContentTypeID=1</link><pubDate>Fri, 31 Jul 2009 11:01:26 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:c86c0a8f-6062-4806-bfa0-3486a91c7646</guid><dc:creator>ImPer Westermark</dc:creator><description>&lt;p&gt;&lt;p&gt;
The problem example in my first post was for a processor that
auto-acknowledges status bits as they are read. That means that the
software must do one (1) read and then process all bits.&lt;/p&gt;

&lt;p&gt;
The solution to that (if we ignore other problems with bit fields)
is to copy the register value once to a union of an unsigned and the
bit fields and write:&lt;/p&gt;

&lt;pre&gt;
com1_status_t tmp_status;

// Sample and acknowledge  status bits.
tmp_status.raw = com1_status;
// Process any detected errors
if (tmp_status.b.rx_overrun) ...
if (tmp_status.b.rx_parity) ...
&lt;/pre&gt;

&lt;p&gt;
The problem example in the later post was for a processor where
you write a &amp;#39;1&amp;#39; to a bit position to a write-only register
overlapping the status register to acknowledge a specific event.&lt;/p&gt;

&lt;p&gt;
Such a processor does not have a problem with multiple read
operations - a later read may possibly pick up one or more extra
bits, but that isn&amp;#39;t dangerous. But such a processor does not allow a
read-modify-write for acknowledging a single bit since the design has
a read-only register overlapping a write-only register.&lt;/p&gt;

&lt;p&gt;
Alas, I managed to **** up the example of the old-style solution.
There shouldn&amp;#39;t have been any |= in the assign, but just an assign.
Sorry for the confusion.&lt;/p&gt;

&lt;pre&gt;
t0ir = TxIR_MR1; // Safe acknowledge of MR1 since no read-modify-write
&lt;/pre&gt;

&lt;p&gt;
The solution to the second problem, if using bit-fields (and
ignoring all the other problems with bit-fields) is to use a
temporary union of an unsigned and bit fields for the acknowledge
part:&lt;/p&gt;

&lt;pre&gt;
timer_ir_t ack;
ack.raw = 0; // Don&amp;#39;t know anything to acknowledge yet
if (t0ir.b.tm0) {
    // handle event.
    ack.b.tm0 = 1; // should ack tm0 - read-modify-write in RAM is safe
}
if (t0ir.b.tm1) {
    // handle tm1 event.
    ack.b.tm1 = 1; // should ack tm1 - read-modify-write in RAM is safe
}
...
t0ir.raw = ack.raw; // acknowledge processed events - no read-modify-write, just a write
&lt;/pre&gt;

&lt;p&gt;
One thing here is that when moving between different ARM
compilers, the ARM ABI locks down the behaviour of bit-fields by
being way stricter than the C language standard. But when leaving the
ARM world, it isn&amp;#39;t even known if the bits will be allocated
low-to-high or high-to-low, so switching between two different
compilers but staying with the same processor can completely break
everything.&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: incorrect behavior with [somewhat] complex struct...</title><link>https://community.arm.com/thread/152856?ContentTypeID=1</link><pubDate>Fri, 31 Jul 2009 10:31:22 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:28516336-5ee8-4afa-b82a-bd5b8ece4cf3</guid><dc:creator>ImPer Westermark</dc:creator><description>&lt;p&gt;&lt;p&gt;
No. If you pack the data each union will shrink to 1 byte and you
will need a 6th byte for the 6 reserved bits you have last.&lt;/p&gt;

&lt;p&gt;
That means that the 2 bytes of the u16 will be overlaid with 6
bytes.&lt;/p&gt;

&lt;p&gt;
Your unions module1, module2, module3, module4 and module5 will
not magically merge into a single 16-bit container.&lt;/p&gt;

&lt;p&gt;
Paragraph 6.7.2.1 of the C standard says in section 13 that
&amp;quot;Within a structure object, the non-bit-field members and the units
in which bit-fields&lt;br /&gt;
reside have addresses that increase in the order in which they are
declared.&amp;quot;&lt;/p&gt;

&lt;p&gt;
In 14, the standard specifies that &amp;quot;A pointer to a&lt;br /&gt;
union object, suitably converted, points to each of its members (or
if a member is a bitfield,&lt;br /&gt;
then to the unit in which it resides), and vice versa.&amp;quot;&lt;/p&gt;

&lt;p&gt;
The language standard will not merge your bit fields since that
would mean that the struct directly following the u16 would have
multiple members having the same address. But only a union may have
multiple members with the same address.&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: incorrect behavior with [somewhat] complex struct...</title><link>https://community.arm.com/thread/152855?ContentTypeID=1</link><pubDate>Fri, 31 Jul 2009 10:23:07 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:54faa21e-7c93-44dd-b787-6f5350cfd9f4</guid><dc:creator>stephen phillips</dc:creator><description>&lt;p&gt;&lt;p&gt;
I believe what Per was saying (although if you get lost in the
discussion it has the distinct possibility of being lost). Do not
rely on the compiler to deal with the hardware in a certain manner.
This is VERY important especially if you change processors (which I
have done numerous tmies) or compilers (same there).&lt;/p&gt;

&lt;p&gt;
What I garnered is that he was suggesting using the compiler for
what is known to work with normal C/C++ conventions in ALL compilers.
That is use the &amp;#39;ugly&amp;#39; standard C &amp;#39;&amp;amp;&amp;#39; &amp;#39;|&amp;#39; operators so that it
will work irregardless of the compilers arbitrary support methods for
bit fields.&lt;/p&gt;

&lt;p&gt;
The assumption that the compiler you have available (IE Turbo C++
Borland C++ GCC {in it&amp;#39;s numerous incarnations} ) will work the same
irregardless of what target or version you are using is a bad
one.&lt;/p&gt;

&lt;p&gt;
Summary make your code blatantly obvious what it is doing, and
comment it heavily. So that no one can guess what is being modified.
Do not rely on any feature of a compiler (again bit fields is the
example) to make the code work. Readability also includes
understanding what is being done and why, not just having nice
looking code (that hides lots of potential problems, and sins, EX one
small change is made such as recompiling the project with a different
version of the compiler).&lt;/p&gt;

&lt;p&gt;
A good resource is &lt;a href="http://www.ganssle.com/"&gt;http://www.ganssle.com/&lt;/a&gt; and &lt;a target="" href="http://www.embedded.com"&gt;&lt;a href="http://www.embedded.com"&gt;http://www.embedded.com&lt;/a&gt;&lt;/a&gt;
for this, and numerous other problems you might encounter.&lt;/p&gt;

&lt;p&gt;
Stephen&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: incorrect behavior with [somewhat] complex struct...</title><link>https://community.arm.com/thread/148101?ContentTypeID=1</link><pubDate>Fri, 31 Jul 2009 09:49:13 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:3779eb19-6452-43c6-9e73-7cd56c0a1e4b</guid><dc:creator>David Sudolcan</dc:creator><description>&lt;p&gt;&lt;p&gt;
And... getting back to the original question, could I have used
the __packed attribute to make the original code work like I expected
it to (i.e., to shrink the number of bytes required to implement the
ioflags variables to the min size possible)?&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: incorrect behavior with [somewhat] complex struct...</title><link>https://community.arm.com/thread/147533?ContentTypeID=1</link><pubDate>Fri, 31 Jul 2009 09:34:06 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:d946b170-c590-4ed4-be45-d1787dc45833</guid><dc:creator>Marcus Harnisch</dc:creator><description>&lt;p&gt;&lt;p&gt;
Hi Per&lt;/p&gt;

&lt;p&gt;
Of course we have moved far off topic by now. The OP asked about
a&lt;br /&gt;
data structure and not HW registers.&lt;/p&gt;

&lt;p&gt;
&amp;gt; It is so very easy to write code like the following:&lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt; [...]&lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt; So when the developer thinks that he acknowledges one timer
event,&lt;br /&gt;
&amp;gt; the ARM will read the T0IR register and potentially pick up a
number&lt;br /&gt;
&amp;gt; of set fields that will be or:ed with the bit the programmer&lt;br /&gt;
&amp;gt; intended to acknowledge. The net result is a potential loss of
some&lt;br /&gt;
&amp;gt; timer events.&lt;/p&gt;

&lt;p&gt;
Yes that is true.&lt;/p&gt;

&lt;p&gt;
&amp;gt; If using the more visible alternative, using standard or/and
code,&lt;br /&gt;
&amp;gt; the above would have looked like:&lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt; [...]&lt;/p&gt;

&lt;p&gt;
Hmm, and in which way does the second example differ from the
first&lt;br /&gt;
one? Both ISR read the control register multiple times and may
loose&lt;br /&gt;
timer events. In fact I compiled both versions and with the
exception&lt;br /&gt;
of a single instruction the code is identical as expected. I fail
to&lt;br /&gt;
see the advantage of the second solution.&lt;/p&gt;

&lt;p&gt;
Please provide a full minimal example that demonstrates what you
were&lt;br /&gt;
thinking of.&lt;/p&gt;

&lt;p&gt;
Thanks&lt;br /&gt;
Marcus&lt;br /&gt;
&lt;a href="http://www.doulos.com/arm/"&gt;http://www.doulos.com/arm/&lt;/a&gt;&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: incorrect behavior with [somewhat] complex struct...</title><link>https://community.arm.com/thread/146409?ContentTypeID=1</link><pubDate>Thu, 30 Jul 2009 12:48:22 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:744d9610-c2eb-4be5-aa74-ee1615c9e602</guid><dc:creator>ImPer Westermark</dc:creator><description>&lt;p&gt;&lt;p&gt;
&amp;quot;If you modify all bits in the field, you still have to mask the
other bits in the container, no? Could you give an example,
please?&amp;quot;&lt;/p&gt;

&lt;p&gt;
Normally yes, but there are two special cases.&lt;/p&gt;

&lt;p&gt;
When I want to set all bits in one field to one, the compiler can
directly do the &amp;quot;or&amp;quot; operation, without first masking any other
fields.&lt;/p&gt;

&lt;p&gt;
When I want to clear all bits in one field to zero, the compiler
don&amp;#39;t need to perform any &amp;quot;or&amp;quot; operation - it is enough to just do
the &amp;quot;and not&amp;quot; to keep everything but this field.&lt;/p&gt;

&lt;p&gt;
I have seen compilers that have missed this optimization for
fields bigger than one bit. The ARM compiler managing to do a
clear+set for a one-bit field was a first. But it was only with zero
optimization so it isn&amp;#39;t something I would see as a problem.&lt;/p&gt;

&lt;p&gt;
But as you have already noted, such optimization failures can be
corrected in the next version of the compiler.&lt;/p&gt;

&lt;p&gt;
Another thing that can sometimes be funny with some compilers is
if you use signed fields. I have seen compilers generating very
interesting code then, because of the need of sign-extend when you
assign. This is normally a problem with microcontrollers, since you
would normally only map unsigned fields to SFR.&lt;/p&gt;

&lt;p&gt;
About the example I showed earlier. Yes, any competent programmer
should read out the register value into a temporary variable before
processing the bits. And I do expect people who writes drivers/ISR to
have read the relevant parts of the datasheet. But that doesn&amp;#39;t
always happens when a software gets old and the responsibility moved
to some new guy/gal just out from school and where just some very
minor changes are expected.&lt;/p&gt;

&lt;p&gt;
The previous example whas a bit &amp;quot;odd&amp;quot; in that few processors
perform auto-acknowledge for a interrupt or status register.
Auto-acknowledge is normally reserved for the RX register of a
communication port. But what is quite common is that you have an
interrupt register where each bit flags an interrupt source, and you
then write a one to that bit to acknowledge. An example is the timer
interrupt register in a NXP LPC17xx (Cortex-M3) or LPC23xx (ARM7)
chip.&lt;/p&gt;

&lt;p&gt;
It is so very easy to write code like the following:&lt;/p&gt;

&lt;pre&gt;
void handle_timer0_irq() {
    if (t0ir.mr0) {
        // Handle match 0
        t0ir.mr0 = 1; // Acknowledge MR0 (###)
    }
    if (t0ir.mr1) {
        // Handle match 1
        t0ir.mr1 = 1; // Acknowledge MR1 (###)
    }
    //...
    if (t0ir.cr0) {
        // Handle capture channel 0
        t0ir.cr0 = 1; // Acknowledge CR0 (###)
    }
    if (t0ir.cr1) {
        // Handle capture channel 1
        t0ir.cr1 = 1; // Acknowledge CR0 (###)
    }
}
&lt;/pre&gt;

&lt;p&gt;
&lt;br /&gt;
The application may normally expect only one interrupt flag at a
time, but it isn&amp;#39;t impossible that you may have multiple timer events
so close together that several is trigged before you enter the ISR,
or that one more event happens while in the above code.&lt;/p&gt;

&lt;p&gt;
Each of the ### represents an acknowledge of one (1) timer event,
but since we are talking about bit fields, the ARM ABI requires a
read and a write of the full container for every field assign.&lt;/p&gt;

&lt;p&gt;
So when the developer thinks that he acknowledges one timer event,
the ARM will read the T0IR register and potentially pick up a number
of set fields that will be or:ed with the bit the programmer intended
to acknowledge. The net result is a potential loss of some timer
events.&lt;/p&gt;

&lt;p&gt;
If using the more visible alternative, using standard or/and code,
the above would have looked like:&lt;/p&gt;

&lt;pre&gt;
enum {
    TxIR_MR0 = 1u &amp;lt;&amp;lt; 0,
    TxIR_MR1 = 1u &amp;lt;&amp;lt; 1,
    TxIR_MR2 = 1u &amp;lt;&amp;lt; 2,
    TxIR_MR3 = 1u &amp;lt;&amp;lt; 3,
    TxIR_CR0 = 1u &amp;lt;&amp;lt; 4,
    TxIR_CR1 = 1u &amp;lt;&amp;lt; 5,
    ...
};
void handle_timer0_irq() {
    if (t0ir &amp;amp; TxIR_MR0) {
        // Handle match 0
        t0ir |= TxIR_MR0; // Safe acknowledge of MR0
    }
    if (t0ir &amp;amp; TxIR_MR1) {
        // Handle match 1
        t0ir |= TxIR_MR1; // Safe acknowledge of MR1
    }
    //...
    if (t0ir &amp;amp; TxIR_CR0) {
        // Handle capture channel 0
        t0ir |= TxIR_CR0; // Safe acknowledge of CR0
    }
    if (t0ir.cr1) {
        // Handle capture channel 1
        t0ir |= TxIR_CR1; // Safe acknowledge of CR1
    }
}
&lt;/pre&gt;

&lt;p&gt;
&lt;br /&gt;
In the end, there is nothing wrong with bit fields. It is just that
you always have to think about the hidden &amp;quot;bonus&amp;quot; you may get.&lt;/p&gt;

&lt;p&gt;
If you are using bit fields, you may find that you need to spend
more time adding extra comments than what you save from the neater
code.&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: incorrect behavior with [somewhat] complex struct...</title><link>https://community.arm.com/thread/144674?ContentTypeID=1</link><pubDate>Thu, 30 Jul 2009 09:35:34 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:3f864a3e-abab-4521-8ea1-fb9b229bce4f</guid><dc:creator>Marcus Harnisch</dc:creator><description>&lt;p&gt;&lt;p&gt;
Hi Per&lt;/p&gt;

&lt;p&gt;
&amp;gt; I was thinking about that junior developer who gets the
support of the&lt;br /&gt;
&amp;gt; software a couple of years from now. He sees assigns to&lt;br /&gt;
&amp;gt; &amp;lt;container&amp;gt;.&amp;lt;field&amp;gt; and decides to make some
modification, adding one&lt;br /&gt;
&amp;gt; more such assign. But what isn&amp;#39;t visible when reading the *.c
files,&lt;br /&gt;
&amp;gt; is that the assign to the field did not just write to the named
field,&lt;br /&gt;
&amp;gt; but did perform one read and one write of the full
container.&lt;/p&gt;

&lt;p&gt;
We were talking about different things then. Sorry. I was
referring to&lt;br /&gt;
the rules of access to volatile bit field structs with multiple,&lt;br /&gt;
perhaps overlapping (yuck!) containers.&lt;/p&gt;

&lt;p&gt;
&amp;gt; If mapping such a regsiter to bit fields, the expression&lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt; if (com1.status.rx_overrun) ...&lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt; would automagically also clear any reported framing, parity,&lt;br /&gt;
&amp;gt; ... errors that may have been detected.&lt;/p&gt;

&lt;p&gt;
But since you carefully read the data sheet before starting to
write&lt;br /&gt;
code I am sure that you copied the entire register into a local&lt;br /&gt;
variable before accessing its contents :^)&lt;/p&gt;

&lt;p&gt;
Seriously, I see the issue, but I fail to see in which way any
other&lt;br /&gt;
approach would be safer. Does something like&lt;/p&gt;

&lt;pre&gt;
if (com1.status &amp;amp; COM_STATUX_RX_OVERRUN) ...
&lt;/pre&gt;

&lt;p&gt;
make a difference here?&lt;/p&gt;

&lt;p&gt;
&amp;gt; When compiled for a Cortex-M3 processor (Thumb2 instruction
set) with&lt;br /&gt;
&amp;gt; -O0, the following code is generated (b2 is a one-bit
field):&lt;br /&gt;
&amp;gt; [...]&lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt; Switching from a Cortex-M3 processor to a processor with full
32-bit&lt;br /&gt;
&amp;gt; ARM instructions, the compiler manages without the clear even
ast&lt;br /&gt;
&amp;gt; -O0:&lt;/p&gt;

&lt;p&gt;
With a CM3 target I can reproduce this. Strange indeed. Thanks for
the&lt;br /&gt;
additional info.&lt;/p&gt;

&lt;p&gt;
&amp;gt; I wasn&amp;#39;t talking about the assign of all fields in a
container, but&lt;br /&gt;
&amp;gt; a set or clear of all bits in a single field. When setting all
bits,&lt;br /&gt;
&amp;gt; no mask operation is needed. When clearing all fields, no or
is&lt;br /&gt;
&amp;gt; needed.&lt;/p&gt;

&lt;p&gt;
Understand now what you meant but I don&amp;#39;t seem to get it. If
you&lt;br /&gt;
modify all bits in the field, you still have to mask the other bits
in&lt;br /&gt;
the container, no? Could you give an example, please?&lt;/p&gt;

&lt;p&gt;
Thanks&lt;br /&gt;
Marcus&lt;br /&gt;
&lt;a href="http://www.doulos.com/arm/"&gt;http://www.doulos.com/arm/&lt;/a&gt;&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: incorrect behavior with [somewhat] complex struct...</title><link>https://community.arm.com/thread/144675?ContentTypeID=1</link><pubDate>Thu, 30 Jul 2009 05:20:48 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:4d965f6d-dc30-447e-8d57-1267df5d68cd</guid><dc:creator>Ashley Madison</dc:creator><description>&lt;p&gt;&lt;p&gt;
&amp;quot;I was talking about transparency.&amp;quot;&lt;/p&gt;

&lt;p&gt;
Per, I think people will benefit a lot from your presence here if
you stop talking.&lt;/p&gt;

&lt;p&gt;
ciao.&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: incorrect behavior with [somewhat] complex struct...</title><link>https://community.arm.com/thread/142371?ContentTypeID=1</link><pubDate>Wed, 29 Jul 2009 16:58:14 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:b1761d9f-eb68-4130-96fa-056f6544b0b5</guid><dc:creator>ImPer Westermark</dc:creator><description>&lt;p&gt;&lt;p&gt;
&amp;quot;Sorry, but this is a made up example. Possible in theory, but in
real life HW registers just won&amp;#39;t consist of multiple
containers.&amp;quot;&lt;/p&gt;

&lt;p&gt;
There is a saying that if sometihng seems to be too good to be
true, it usually is.&lt;/p&gt;

&lt;p&gt;
If you find it very unlikely that a hardware has a HW register
consisting of multiple containers, why are you then convinced that I
was discussing such a &amp;quot;made up example&amp;quot;?&lt;/p&gt;

&lt;p&gt;
I was talking about transparency.&lt;/p&gt;

&lt;p&gt;
I was thinking about that junior developer who gets the support of
the software a couple of years from now. He sees assigns to
&amp;lt;container&amp;gt;.&amp;lt;field&amp;gt; and decides to make some
modification, adding one more such assign. But what isn&amp;#39;t visible
when reading the *.c files, is that the assign to the field did not
just write to the named field, but did perform one read and one write
of the full container.&lt;/p&gt;

&lt;p&gt;
And quite a number of processors have SFR where a read or a write
has some form of side effect. And that side effect is not always
immediately visible, so an introduced bug can survive a long time
before people start to notice the result of that extra side
effect.&lt;/p&gt;

&lt;p&gt;
One processor I worked with in a project had a status register
where a read reported all error cases seen since the previous read.
No need to write to any register to acknowledge the error flags -
just reading them was enough to also clear them.&lt;/p&gt;

&lt;p&gt;
If mapping such a regsiter to bit fields, the expression&lt;/p&gt;

&lt;pre&gt;
if (com1.status.rx_overrun) ...
&lt;/pre&gt;

&lt;p&gt;
&lt;br /&gt;
would automagically also clear any reported framing, parity, ...
errors that may have been detected.&lt;/p&gt;

&lt;pre&gt;
void set_bit(void) {
    FIO0PIN_BITS.b2 = 1;
}
&lt;/pre&gt;

&lt;p&gt;
&lt;br /&gt;
When compiled for a Cortex-M3 processor (Thumb2 instruction set) with
-O0, the following code is generated (b2 is a one-bit field):&lt;/p&gt;

&lt;pre&gt;
   120: void set_bit(void) {
0x000001CA 4770      BX       lr
   121:     FIO0PIN_BITS.b2 = 1;
0x000001CC 480D      LDR      r0,[pc,#52]  ; @0x00000204
0x000001CE 6940      LDR      r0,[r0,#0x14]
0x000001D0 F0200004  BIC      r0,r0,#0x04
0x000001D4 1D00      ADDS     r0,r0,#4
0x000001D6 490B      LDR      r1,[pc,#44]  ; @0x00000204
0x000001D8 6148      STR      r0,[r1,#0x14]
   122: }
&lt;/pre&gt;

&lt;p&gt;
When compiled with -O1, the problem is solved:&lt;/p&gt;

&lt;pre&gt;
   120: void set_bit(void) {
0x000001C4 4770      BX       lr
   121:     FIO0PIN_BITS.b2 = 1;
0x000001C6 4809      LDR      r0,[pc,#36]  ; @0x000001EC
0x000001C8 6941      LDR      r1,[r0,#0x14]
0x000001CA F0410104  ORR      r1,r1,#0x04
0x000001CE 6141      STR      r1,[r0,#0x14]
   122: }
&lt;/pre&gt;

&lt;p&gt;
Switching from a Cortex-M3 processor to a processor with full
32-bit ARM instructions, the compiler manages without the clear even
ast -O0:&lt;/p&gt;

&lt;pre&gt;
   124: void set_bit(void) {
0x00000130  E12FFF1E  BX        R14
   125:     FIO0PIN_BITS.b2 = 1;
0x00000134  E59F0034  LDR       R0,[PC,#0x0034]
0x00000138  E5901014  LDR       R1,[R0,#0x0014]
0x0000013C  E3811004  ORR       R1,R1,#0x00000004
0x00000140  E5801014  STR       R1,[R0,#0x0014]
   126: }
&lt;/pre&gt;

&lt;p&gt;
Since I&amp;#39;m on vacation right now, I tested the above with the
evaluation version of MDK-ARM 3.70.&lt;/p&gt;

&lt;p&gt;
&amp;quot;True, but compilers have improved over the years and every once
in a while we should revisit our findings from the past.&amp;quot;&lt;/p&gt;

&lt;p&gt;
Correct. But note that I did not write about a specific compiler.
I did write &amp;quot;But with some compilers, the compiler will produce worse
code than if you manually mask the bits.&amp;quot;&lt;br /&gt;
That should be read as: Do not assume that the compiler you have will
produce good code for bit fields - check first!&lt;/p&gt;

&lt;p&gt;
Compound literals helps assign all field values in a single
assign. Just note that you may find C++ compilers that will not
support it. ARMCC and gnuarm does support it also for C++
sources.&lt;/p&gt;

&lt;p&gt;
But you seem to have brought up compound literals as a response to
my sentence &amp;quot;when your assign clears or sets all bits of the bit
field&amp;quot;. I wasn&amp;#39;t talking about the assign of all fields in a
container, but a set or clear of all bits in a single field. When
setting all bits, no mask operation is needed. When clearing all
fields, no or is needed.&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: incorrect behavior with [somewhat] complex struct...</title><link>https://community.arm.com/thread/144671?ContentTypeID=1</link><pubDate>Wed, 29 Jul 2009 15:15:47 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:366a42d5-3d45-4e5a-b119-2fb751075a92</guid><dc:creator>ImPer Westermark</dc:creator><description>&lt;p&gt;&lt;p&gt;
Ashley - thank you for yet one more very meaningful post that adds
important information to a debate.&lt;/p&gt;

&lt;p&gt;
Keep the good work up.&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: incorrect behavior with [somewhat] complex struct...</title><link>https://community.arm.com/thread/142370?ContentTypeID=1</link><pubDate>Wed, 29 Jul 2009 13:56:43 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:b83b7be0-06c6-4aad-a063-53a222b1f85e</guid><dc:creator>Ashley Madison</dc:creator><description>&lt;p&gt;&lt;p&gt;
&amp;#39;Please check out C99 compound literals.&amp;#39;&lt;/p&gt;

&lt;p&gt;
you lost Per right there.&lt;/p&gt;

&lt;p&gt;
:)&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: incorrect behavior with [somewhat] complex struct...</title><link>https://community.arm.com/thread/139254?ContentTypeID=1</link><pubDate>Wed, 29 Jul 2009 10:03:31 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:1070244c-6258-4e2e-96ca-452649d561c4</guid><dc:creator>Marcus Harnisch</dc:creator><description>&lt;p&gt;&lt;p&gt;
Hi Per&lt;/p&gt;

&lt;p&gt;
&amp;gt; But with some compilers, the compiler will produce worse code
than if&lt;br /&gt;
&amp;gt; you manually mask the bits.&lt;/p&gt;

&lt;p&gt;
True, but compilers have improved over the years and every once in
a&lt;br /&gt;
while we should revisit our findings from the past.&lt;/p&gt;

&lt;p&gt;
&amp;gt; One funny thing with the ARM compiler in the MDK is that if
you build&lt;br /&gt;
&amp;gt; without optimization and assign the value 1 to a single-bit
field, the&lt;br /&gt;
&amp;gt; compiler will first add code to clear that bit to a known
state,&lt;br /&gt;
&amp;gt; before setting the bit. With optimization on, this redundant
clear&lt;br /&gt;
&amp;gt; will be removed. Even for 1-bit fields, the compiler goes the
full&lt;br /&gt;
&amp;gt; and/or route.&lt;/p&gt;

&lt;p&gt;
Sorry, I can&amp;#39;t reproduce this with MDK or RVDS.&lt;/p&gt;

&lt;p&gt;
&amp;gt; There are compilers that will fail to optimize away the &amp;quot;and&amp;quot;
or the&lt;br /&gt;
&amp;gt; &amp;quot;or&amp;quot; when your assign clears or sets all bits of the bit
field.&lt;/p&gt;

&lt;p&gt;
Please check out C99 compound literals. If that is not good
enough, I&lt;br /&gt;
define registers as unions of an (anonymous) bit field structure
and&lt;br /&gt;
a uint32_t. To initialize the entire value, I can write to the&lt;br /&gt;
integer element.&lt;/p&gt;

&lt;p&gt;
&amp;gt; A big problem with bit fields in relation to volatile memory
addresses&lt;br /&gt;
&amp;gt; such as SFR, is that they tend to fool the developer into
believing&lt;br /&gt;
&amp;gt; that you are reading or writing a variable named
&amp;lt;container&amp;gt;.&amp;lt;field&amp;gt;,&lt;br /&gt;
&amp;gt; when the processor in reality will read and write a variable
named&lt;br /&gt;
&amp;gt; &amp;lt;container&amp;gt;.&lt;/p&gt;

&lt;p&gt;
The proper behavior of volatile complex bit field structures is
rather&lt;br /&gt;
difficult to comprehend, indeed. But please ask yourself whether
you&lt;br /&gt;
have ever been in a situation where this was an issue.&lt;/p&gt;

&lt;p&gt;
Either you have a (volatile) HW register set which consists of
only&lt;br /&gt;
one container per register (else you should rethink the structure&lt;br /&gt;
definition), or you have a complex data structure (perhaps a
packet&lt;br /&gt;
header) which you normally wouldn&amp;#39;t want to be volatile anyway.&lt;/p&gt;

&lt;p&gt;
&amp;gt; It is very easy to miss that since a full-register access is
made,&lt;br /&gt;
&amp;gt; you may trig unexpected features, such as acknowledging the&lt;br /&gt;
&amp;gt; reception of a byte on the UART, or acknowledging an interrupt,
or&lt;br /&gt;
&amp;gt; starting a new A/D conversion.&lt;/p&gt;

&lt;p&gt;
Sorry, but this is a made up example. Possible in theory, but in
real&lt;br /&gt;
life HW registers just won&amp;#39;t consist of multiple containers.&lt;/p&gt;

&lt;p&gt;
Best regards&lt;br /&gt;
Marcus&lt;br /&gt;
&lt;a href="http://www.doulos.com/arm/"&gt;http://www.doulos.com/arm/&lt;/a&gt;&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: incorrect behavior with [somewhat] complex struct...</title><link>https://community.arm.com/thread/135860?ContentTypeID=1</link><pubDate>Mon, 27 Jul 2009 08:13:47 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:0a0b9c64-24c9-4d4c-a451-72a4630bd2e0</guid><dc:creator>ImPer Westermark</dc:creator><description>&lt;p&gt;&lt;p&gt;
No, I just thought that since you did bring up the ARM ABI, I
would mention that the ARM ABI produces the same result as gcc does
for a 32-bit x86 processor.&lt;/p&gt;

&lt;p&gt;
Yes, the source code will look cleaner with bit fields. But with
some compilers, the compiler will produce worse code than if you
manually mask the bits.&lt;/p&gt;

&lt;p&gt;
One funny thing with the ARM compiler in the MDK is that if you
build without optimization and assign the value 1 to a single-bit
field, the compiler will first add code to clear that bit to a known
state, before setting the bit. With optimization on, this redundant
clear will be removed. Even for 1-bit fields, the compiler goes the
full and/or route.&lt;/p&gt;

&lt;p&gt;
There are compilers that will fail to optimize away the &amp;quot;and&amp;quot; or
the &amp;quot;or&amp;quot; when your assign clears or sets all bits of the bit
field.&lt;/p&gt;

&lt;p&gt;
A big problem with bit fields in relation to volatile memory
addresses such as SFR, is that they tend to fool the developer into
believing that you are reading or writing a variable named
&amp;lt;container&amp;gt;.&amp;lt;field&amp;gt;, when the processor in reality will
read and write a variable named &amp;lt;container&amp;gt;. It is very easy to
miss that since a full-register access is made, you may trig
unexpected features, such as acknowledging the reception of a byte on
the UART, or acknowledging an interrupt, or starting a new A/D
conversion.&lt;/p&gt;

&lt;p&gt;
With code looking like:&lt;/p&gt;

&lt;pre&gt;
register = (register &amp;amp; ~FIELD_MASK) | (field_state &amp;lt;&amp;lt; FIELD_SHIFT);
&lt;/pre&gt;

&lt;p&gt;
&lt;br /&gt;
every reader will clearly see that there was one read and one write
of the full register. By not hiding the ugly access, it will be
easier for a reader to correlate the code side effects with the
datasheet information.&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: incorrect behavior with [somewhat] complex struct...</title><link>https://community.arm.com/thread/125595?ContentTypeID=1</link><pubDate>Mon, 27 Jul 2009 07:47:47 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:61b41fbb-64e0-4eaf-80cd-57ecadf6ba29</guid><dc:creator>Marcus Harnisch</dc:creator><description>&lt;p&gt;&lt;p&gt;
&amp;gt; Anyway - if you use your ARM compiler and check the sizes,
you will&lt;br /&gt;
&amp;gt; notice that ioflags2 is 4 bytes and ioflags3 is 24 bytes.
And&lt;br /&gt;
&amp;gt; changing all bit fields to u16 will shrink the sizes to 2 and
12&lt;br /&gt;
&amp;gt; bytes.&lt;/p&gt;

&lt;p&gt;
Did I imply anywhere that your analysis was wrong? It was in fact
dead&lt;br /&gt;
on.&lt;/p&gt;

&lt;p&gt;
&amp;gt; Your ARM ABI will not combine the multiple bit fields since
they are&lt;br /&gt;
&amp;gt; not neighbours.&lt;/p&gt;

&lt;p&gt;
With &amp;quot;multi-bit values&amp;quot; I didn&amp;#39;t mean multiple independent bit
field&lt;br /&gt;
structures or containers. Coming up with a &lt;i&gt;readable&lt;/i&gt;,
concise&lt;br /&gt;
implementation of a complex (in terms of number of bit-fields and&lt;br /&gt;
variety of sizes) data structure for e.g. a v6/v7 page table with
just&lt;br /&gt;
CPP macros can turn out to be quite a challenge. Why not leave&lt;br /&gt;
choosing the proper bit operation to the compiler.&lt;/p&gt;

&lt;pre&gt;
d[i] &amp;amp;= ~(ARMV6_L1SECDESC_AP_MASK | ARMV6_L1SECDESC_APX_MASK)
d[i] |=   ARMV6_L1SECDESC_APX_RWNA;
// similar style for other bits
&lt;/pre&gt;
&lt;pre&gt;
typedef struct
{
    unsigned int type    : 2;
    unsigned int b       : 1;
    unsigned int c       : 1;
    unsigned int xn      : 1;
    unsigned int domain  : 4;
    unsigned int p       : 1;
    unsigned int ap      : 2;
    unsigned int tex     : 3;
    unsigned int apx     : 1;
    unsigned int s       : 1;
    unsigned int ng      : 1;
    unsigned int subtype : 1;
    unsigned int ns      : 1;
    unsigned int secbase : 12;
} l1_section_t;

d[i].l1_section.ap  = AP_RWNA;
d[i].l1_section.apx = APX_RWNA;
// similar style for other bits
&lt;/pre&gt;

&lt;p&gt;
Isn&amp;#39;t it just much more elegant using a bit field for this? I
guess we&lt;br /&gt;
tend to prefer what we are used to.&lt;/p&gt;

&lt;p&gt;
Best regards&lt;br /&gt;
Marcus&lt;br /&gt;
&lt;a href="http://www.doulos.com/arm/"&gt;http://www.doulos.com/arm/&lt;/a&gt;&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: incorrect behavior with [somewhat] complex struct...</title><link>https://community.arm.com/thread/125594?ContentTypeID=1</link><pubDate>Mon, 27 Jul 2009 07:21:41 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:b3bd9c88-14ec-4a90-a4ca-4135c5ed5e1c</guid><dc:creator>David Sudolcan</dc:creator><description>&lt;p&gt;&lt;p&gt;
All very interesting and illuminating responses. I did abandon the
bit field concept for my struct, and no longer have the problem.&lt;/p&gt;

&lt;p&gt;
I&amp;#39;ve always used the manual masking of bit fields in the past, but
was looking for a cleaner (i.e., more readable) method; combined with
a way to have a single variable that could be written to or read from
non-volatile memory as a single block of bytes; that also enforced
that *all* of the configuration/setup/operational settings would have
to be in that single block of bytes. Accessing them via the &amp;quot;dot&amp;quot;
operator from the single struct seemed like a logical way to do all
of that.&lt;/p&gt;

&lt;p&gt;
Thanks for all your help.&lt;/p&gt;

&lt;p&gt;
Dave.&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: incorrect behavior with [somewhat] complex struct...</title><link>https://community.arm.com/thread/115099?ContentTypeID=1</link><pubDate>Mon, 27 Jul 2009 06:50:28 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:3daefcb8-3d39-45fb-a1c1-cc188bc5d8e2</guid><dc:creator>ImPer Westermark</dc:creator><description>&lt;p&gt;&lt;p&gt;
&amp;quot;I suppose &amp;#39;implementation&amp;#39; means processor rather than compiler
implementation, as in &amp;#39;ARM may behave differently from x86&amp;#39;, which
could be critical indeed in a SW simulation of your code.&amp;quot;&lt;/p&gt;

&lt;p&gt;
The C standard leaves a lot of these things open to the individual
compiler implementation. In some situations, an OS vendor may then
define an ABI that may lock down some of these open issues for
compilers supporting that OS. In the case of the ARM processor, ARM
has decided to define an ABI since the value if their core is greatly
affected by the portability of code between different ARM processors,
and since ARM is developing their own compilers.&lt;/p&gt;

&lt;p&gt;
But most OS ABI do not bother to define bit fields for the simple
reasons that most OS do not use bit fields. They instead define their
API with manual masking of bits, just because bit fields are so often
avoided.&lt;/p&gt;

&lt;p&gt;
Anyway - if you use your ARM compiler and check the sizes, you
will notice that ioflags2 is 4 bytes and ioflags3 is 24 bytes. And
changing all bit fields to u16 will shrink the sizes to 2 and 12
bytes. Your ARM ABI will not combine the multiple bit fields since
they are not neighbours.&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: incorrect behavior with [somewhat] complex struct...</title><link>https://community.arm.com/thread/103282?ContentTypeID=1</link><pubDate>Mon, 27 Jul 2009 06:22:53 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:1c3121a3-2361-48ac-9b2f-1508e46d243d</guid><dc:creator>Marcus Harnisch</dc:creator><description>&lt;p&gt;&lt;p&gt;
Hi Per&lt;/p&gt;

&lt;p&gt;
Thanks for the detailed analysis.&lt;/p&gt;

&lt;p&gt;
Some things to be clarified here:&lt;/p&gt;

&lt;p&gt;
&amp;gt; Note that the bit fields in C have a number of details that
are left&lt;br /&gt;
&amp;gt; to the implementation.&lt;/p&gt;

&lt;p&gt;
I suppose &amp;quot;implementation&amp;quot; means processor rather than
compiler&lt;br /&gt;
implementation, as in &amp;quot;ARM may behave differently from x86&amp;quot;,
which&lt;br /&gt;
could be critical indeed in a SW simulation of your code.&lt;/p&gt;

&lt;p&gt;
As far as only ARM is concerned, the exact bit field behavior
(modulo&lt;br /&gt;
unintended omissions) is defined in the ARM Architecture
Procedure&lt;br /&gt;
Call Standard (AAPCS), which is available as PDF. ARM ABI
compliant&lt;br /&gt;
compilers must implement these rules.&lt;/p&gt;

&lt;p&gt;
&amp;gt; I would implement your code using traditional bit
operations.&lt;/p&gt;

&lt;p&gt;
Setting up bit fields in C can be a royal pain at first, but it
often&lt;br /&gt;
pays off when you use them a lot in code.&lt;/p&gt;

&lt;p&gt;
In this case of single bit values, I might agree with you. If you
have&lt;br /&gt;
to deal with multi-bit values though, the necessary bit masking&lt;br /&gt;
decreases readability a lot. And as DEK says (approximately from
my&lt;br /&gt;
memory) &amp;quot;code gets written once, but will be read hundreds of
times&amp;quot;.&lt;/p&gt;

&lt;p&gt;
My apologies for mentioning &amp;quot;intellisense&amp;quot;-like features as
another&lt;br /&gt;
argument for bit fields...&lt;/p&gt;

&lt;p&gt;
Best regards&lt;br /&gt;
Marcus&lt;br /&gt;
&lt;a href="http://www.doulos.com/arm/"&gt;http://www.doulos.com/arm/&lt;/a&gt;&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: incorrect behavior with [somewhat] complex struct...</title><link>https://community.arm.com/thread/89882?ContentTypeID=1</link><pubDate>Thu, 23 Jul 2009 04:48:57 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:6fa227f8-0af9-46c8-9ed3-beee9578dfb9</guid><dc:creator>ImPer Westermark</dc:creator><description>&lt;p&gt;&lt;p&gt;
I would implement your code using traditional bit operations.&lt;/p&gt;

&lt;pre&gt;
enum {
    MODULE1_RUN         = 0,
    MODULE1_DIRECTION   = 1,
    MODULE2_EXTEND      = 2,
    MODULE2_RETRACT     = 3,
    MODULE2_RUN         = 2,
    MODULE2_DIRECTION   = 3,
    MODULE3_OPEN        = 4,
    MODULE3_CLOSE       = 5,
    MODULE3_RUN         = 4,
    MODULE3_DIRECTION   = 5,
    MODULE4_OPEN        = 6,
    MODULE4_CLOSE       = 7,
    MODULE4_RUN         = 6,
    MODULE4_DIRECTION   = 7,
    MODULE5_FAN         = 9,
    MODULE5_DIRECTION   = 8,
    MODULE5_RUN         = 9,
};

int set_module2_retract(int state) {
    int previous_state;

    if (module2_type() != IOCTL) {
        return -1;
    }
    if (state) {
        set_module1_extend(0);
    }
    previos_state = (variable.ioflags3 &amp;amp; (1u &amp;lt;&amp;lt; MODULE2_RETRACT)) != 0;
    if (state) {
        variable.ioflags3 |= 1u &amp;lt;&amp;lt; MODULE2_RETRACT;
    } else {
        variable.ioflags3 &amp;amp;= ~(1u &amp;lt;&amp;lt; MODULE2_RETRACT);
    }
    return previous_state;
}
&lt;/pre&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: incorrect behavior with [somewhat] complex struct...</title><link>https://community.arm.com/thread/56470?ContentTypeID=1</link><pubDate>Thu, 23 Jul 2009 03:56:33 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:e3e924e3-be4d-4815-abd1-cb876b5883a5</guid><dc:creator>ImPer Westermark</dc:creator><description>&lt;p&gt;&lt;p&gt;
You are making expectations that are not always true.&lt;/p&gt;

&lt;p&gt;
Note that the bit fields in C have a number of details that are
left to the implementation.&lt;/p&gt;

&lt;p&gt;
You have a struct that contains multiple unions that each contain
bitfields. Don&amp;#39;t expect the compiler to concatenate all this into a
single continuous bit field container.&lt;/p&gt;

&lt;p&gt;
gcc or M$ Visual C++ that generates 32-bit code will think that
sizeof(ioflags2) is 4 bytes (because the bitfields are unsigned). It
will think the ioflags3 combo is 24 bytes. Replacing the unsigned bit
fields with u16 would shrink ioflags2 to 2 bytes and ioflags3 to 12
bytes.&lt;/p&gt;

&lt;p&gt;
Look closer at ioflags3.&lt;/p&gt;

&lt;p&gt;
It is a union of a u16 and a struct.&lt;br /&gt;
The u16 is 2 bytes large. But how large is the struct?&lt;br /&gt;
The struct has the following elements:&lt;br /&gt;
module1 - maybe 1, maybe 2, maybe 4, ... bytes&lt;br /&gt;
module2 - maybe 1, maybe 2, ...&lt;br /&gt;
module3 - maybe 1, maybe 2, ...&lt;br /&gt;
module4 - maybe 1, maybe 2, ...&lt;br /&gt;
module5 - maybe 1, maybe 2, ...&lt;/p&gt;

&lt;p&gt;
For 32-bit gcc, each of module1..module5 will be four bytes large
if the bit fields in them are declared unsigned, since unsigned is a
32-bit integer.&lt;/p&gt;

&lt;p&gt;
For 32-bit gcc, each of module1..module5 will be two bytes large
if the bit fields in them are declared u16.&lt;/p&gt;

&lt;p&gt;
But the bit fields in module1 will not share the same unsigned or
u16 as the bitfields in module2 or module3, even if the container is
large enough to store the 10 bits.&lt;/p&gt;

&lt;p&gt;
Never expect to get portable code when using bit fields. If you do
use them - verify with sizeof() that you get the expected size. And
verify that each field will affect exactly the bits you think they
will affect.&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>