Hi all (and Eric),
I have a question about scalar_storage_order and support of type
punning between types that have different byte order.
Take:
typedef unsigned char uint8_t;
typedef unsigned int uint32_t;
#define __big_endian__ scalar_storage_order("big-endian")
#define __little_endian__ scalar_storage_order("little-endian")
typedef union {
uint32_t val;
uint8_t v[4];
} __attribute__((__big_endian__)) upal_u32be_t;
typedef union {
uint32_t val;
uint8_t v[4];
} __attribute__((__little_endian__)) upal_u32le_t;
static inline uint32_t native_to_big_endian(uint32_t t)
{
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
return t;
#else
return __builtin_bswap32(t);
#endif
}
static inline uint32_t native_to_little_endian(uint32_t t)
{
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
return __builtin_bswap32(t);
#else
return t;
#endif
}
void link_error(void);
#ifndef __OPTIMIZE__
void link_error(void)
{
__builtin_abort ();
}
#endif
#define test(p, p1, i) do { if (p[i] != p1[i]) link_error (); } while (0)
#define tests(p, p1) do { test(p, p1, 0); test(p, p1, 1); \
test(p, p1, 2); test(p, p1, 3); } while (0)
int main(void)
{
uint8_t *p, *p1;
uint32_t u = 0x12345678;
uint32_t bu = ((upal_u32be_t*)&u)->val;
uint32_t b1u = native_to_big_endian(u);
p = (uint8_t*)&bu;
p1 = (uint8_t*)&b1u;
tests(p, p1);
u = 0x12345678;
uint32_t lu = ((upal_u32le_t*)&u)->val;
uint32_t l1u = native_to_little_endian(u);
p = (uint8_t*)&lu;
p1 = (uint8_t*)&l1u;
tests(p, p1);
return 0;
}
---- CUT ---
Should this be allowed/working everywhere (I mean without considering
PDP byte order)?
Right now this works at -O0, we don't abort but at -O1 and above FRE
and CCP both misbehave in doing a constant prop of 0x12345678 through
the upal_u32le_t/upal_u32be_t access.
I notice this statement in the documentation:
Moreover, the use of type punning or aliasing to toggle the storage
order is not supported; that is to say, a given scalar object cannot
be accessed through distinct types that assign a different storage
order to it.
--- CUT ---
But I am not 100% sure that is the case here but I hope I am wrong in
saying this is not supported.
Thanks,
Andrew