More strict aliasing

Sergei Organov osv at javad.com
Fri Dec 8 13:59:56 UTC 2006


Till Straumann <strauman at ...> writes:
> Here's another example that breaks strict aliasing rules
> but illustrates a scenario quite commonly found
> in a OS/driver environment:

First I should say that I agree that a lot of old code could be 
silently broken by the strict aliasing rules, and that RTEMS 
should better turn off strict aliasing for now. Nevertherless, 
the code that breaks aliasing rules very often have other 
portability problems as well, so review of the RTEMS sources 
with strict aliasing in mind should improve overall 
code quality.

As nobody seem to have a lot of experience "fixing" different 
kinds of aliasing violations, I think we need some self-training
here. Below I suggest 2 ways to fix the first example you've 
provided and I'd like to hear what others think about it.

> 
> Assume we have a device (serial device, ethernet chip, fifo, ...)
> that can only be accessed with 16-bit bus cycles and we code an
> generic 'read' access routine:
> 
> typedef uint16_t  PortType;
> 
> extern volatile PortType *fifo_port;
> 
> static inline void
> rd_fifo(void *item, int n_words)
> {
> PortType *dst = item;
>     while (n_words--)
>        *dst++ = *fifo_port;
> }

Though I think the above "generic" implementation may have 
byte order problems anyway, the C99-compliant approach to it 
would be as follows, I think:

static inline void
rd_fifo(void *item, int n_words)
{
    PortType *dst = item;
    while (n_words--) {
       PortType v = *fifo_port;
       memcpy(dst++, &v, sizeof(v));
    }
}

Where one may wish to replace memcpy with 2 unsigned char* 
accesses if she doesn't trust compiler to optimize memcpy.

Yet another implementation, that has somewhat different 
properties from the point of view of bytes order problems, 
is as follows:

static inline void
rd_fifo(void *item, int n_words)
{
    unsigned char *dst = item;
    for ( ; n_words--; dst += 2) {
       PortType v = *fifo_port;
       dst[0] = v;
       dst[1] = v >> 8;
    }
}

-- Sergei.





More information about the users mailing list