On 6 Jun 2007, at 3:40 AM, Hans Werner Strube wrote:
Hardly. ip6_ctlun is a union, not a struct.

Ah, yes. Of course, you are right. This is what I get for debugging things at 4:00 in the morning (the previous night).

On 6 Jun 2007, at 4:45 AM, Stuart Remphrey wrote:
However, while the ip6_hdrctl union is 64 bits,
it's largest member is only 32 bits.
So it is forced to align to 32 bits, not 64.

But that ought to be fine; IP6_NEQ uses the address field 32 bits at a time.

typedef union   i6addr  {
        u_32_t  i6[4];
        struct  in_addr in4;
        struct  in6_addr in6;
        void    *vptr[2];
        lookupfunc_t    lptr[2];
        struct {
                u_short type;
                u_short subtype;
                char    label[12];
        } i6un;
} i6addr_t;

#define I60(x)  (((i6addr_t *)(x))->i6[0])
#define I61(x)  (((i6addr_t *)(x))->i6[1])
#define I62(x)  (((i6addr_t *)(x))->i6[2])
#define I63(x)  (((i6addr_t *)(x))->i6[3])

#define IP6_NEQ(a,b)    ((I63(a) != I63(b)) || (I62(a) != I62(b)) || \
                         (I61(a) != I61(b)) || (I60(a) != I60(b)))

So, what's causing the alignment problem? Looking at the assembly, it's loading into registers and comparing those values 64 bits at a time. It looks like the compiler (gcc 4.1.2) must be smart enough to notice the kinds of operations IP6_NEQ is doing, and optimizes it down to two 64-bit compares. It's certainly efficient, but is that valid? Someone might not have ensured that the struct was 64-bit aligned! (Assembly version available to anyone who wants to look at it.)

On 64-bit platforms which care about 64-bit alignment
this may need to be enforced via a 64-bit dummy
union member or pragma.

Probably so. Is there a preferred way to do this, given portability and coding style constraints?

Thanks,
- Geoff

Reply via email to