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