On 12/09/17 16:15, paul.kon...@dell.com wrote: > >> On Sep 12, 2017, at 5:32 AM, Jürg Billeter <juerg.bille...@codethink.co.uk> >> wrote: >> >> Hi, >> >> To support applications that assume big-endian memory layout on little- >> endian systems, I'm considering adding support for reversing the >> storage order to GCC. In contrast to the existing scalar storage order >> support for structs, the goal is to reverse the storage order for all >> memory operations to achieve maximum compatibility with the behavior on >> big-endian systems, as far as observable by the application. > > I've done this in the past by C++ type magic. As a general setting > it doesn't make sense that I can see. As an attribute applied to a > particular data item, it does. But I'm not sure why you'd put this in > the compiler when programmers can do it easily enough by defining a "big > endian int32" class, etc. >
Some people use the compiler for C rather than C++ ... If someone wants to improve on the endianness support in gcc, I can think of a few ideas that /I/ think might be useful. I have no idea how difficult they might be to put in practice, and can't say if they would be of interest to others. First, I would like to see endianness given as a named address space, rather than as a type attribute. A key point here is that named address spaces are effectively qualifiers, like "const" and "volatile" - and you can then use them in pointers: big_endian uint32_t be_buffer[20]; little_endian uint32_t le_buffer[20]; void copy_buffers(const big_endian uint32_t * src, little_endian uint32_t * dest) { for (int i = 0; i < 20; i++) { dest[i] = src[i]; // Swaps endianness on copy } } That would also let you use them for scaler types, not just structs, and you could use typedefs: typedef big_endian uint32_t be_uint32_t; Secondly, I would add more endian types. As well as big_endian and little_endian, I would add native_endian and reverse_endian. These could let you write a little clearer definitions sometimes. And ideally I would like mixed endian with big-endian 16-bit ordering and little-endian ordering for bigger types (i.e., 0x87654321 would be stored 0x43, 0x21, 0x87, 0x65). That order matches some protocols, such as Modbus. Third, I'd like to be able to attach the attribute to particular variables and to scalers, not just struct and union types. Forth, I would like type-punning through unions with different ordering to be allowed. I'd like to be able to define: union U { __attribute__((scalar_storage_order("big-endian"))) uint16_t protocol[32]; __attribute__((scalar_storage_order("little-endian"))) struct { uint32_t id; uint16_t command; uint16_t param1; ... } } and then I could access data in little ordering in the structures, then in 16-bit big-endian lumps via the "protocol" array. David