On 07/06/17 11:33, Andrew Haley wrote: > On 07/06/17 10:15, Kirill Yu Berezin wrote: >> My question is. Is this an expected behaviour or I must report a bug ? > > It's not a bug: your code displays undefined behaviour: you're casting > a pointer to struct udp_pseudo fields to an array of uint16_t. This > is never well-defined in C++, but if you really want to do this kind > of thing, use -fno-strict-aliasing. > > See also > http://www.microhowto.info/howto/calculate_an_internet_protocol_checksum_in_c.html >
Two other ideas spring to mind. Use the "may_alias" attribute on the udp_pseudo struct: struct udp_pseudo { uint32_t src; uint32_t dst; uint8_t z; uint8_t proto; uint16_t len; } __attribute__((may_alias)); This tells the compiler that this type may alias other types (such as the uint8_t array). I think you will also need a "may_alias" attribute on the uint16_t pointer in calc_16bit_checksum_part as well. You can imagine "may_alias" attribute as giving you the effect of -fno-strict-aliasing, but only for particular types. The other is to make a union type that has your struct as a field, and your uint8_t array as another field. If you access everything through the union, the compiler knows they alias. Again, you would want to include the uint16_t pointer in this solution in order to get all the aliasing correct.