j
: Next unread message k
: Previous unread message j a
: Jump to all threads
j l
: Jump to MailingList overview
Hello!
The reason OpenBIOS violates the strict aliasing rules so often is because it uses char arrays to represent endian-specific data.
Char arrays may have alignment different from that of the longer types. That's why casting a pointer to such array to a pointer to a longer type and dereferencing it is considered unsafe by the compiler. The compiler assumes that different types would not occupy the same memory unless we tell it not to make such assumption.
Char arrays serve as protection against misusing endian-specific data as host-endian integers. The alternative it to use sparse annotated types, such as __le32. __le32 has the same alignment as u32, but sparse would recognize attempts to use __le32 in arithmetic operations.
I think switching to sparse annotated types would be a good idea whether strict aliasing is disabled or not. It makes the code more readable. It could also fix some hard to find bugs.
The reason OpenBIOS violates the strict aliasing rules so often is because it uses char arrays to represent endian-specific data.
No. The reason it isn't valid C code is simply "because it isn't valid C code". Specifically, it is accessing arrays of chars as another type. This is not allowed.
Char arrays may have alignment different from that of the longer types.
That is not a problem on most architectures. GCC allows it in most (all?) cases.
That's why casting a pointer to such array to a pointer to a longer type and dereferencing it is considered unsafe by the compiler.
It isn't considered "unsafe". It is simply _not valid code_. It is impossible for a compiler to detect (or diagnose!) all invalid code; but the compiler is allowed to assume it is presented with valid code, it can do <whatever> with invalid code.
The compiler assumes that different types would not occupy the same memory unless we tell it not to make such assumption.
It's not an assumption, it is guaranteed (by definition) that in any valid C program, any object is only accessed as its stored type or a character type.
Char arrays serve as protection against misusing endian-specific data as host-endian integers. The alternative it to use sparse annotated types, such as __le32. __le32 has the same alignment as u32, but sparse would recognize attempts to use __le32 in arithmetic operations.
A much better way is to access all data that needs marshalling via some functions that do just that, e.g., read32be(const u8 *) and write16le (u8 *, u8) . It is much more readable, and the compiler knows what you're doing, because it is correct C code.
Segher
On Tue, Aug 11, 2009 at 11:55 PM, Pavel Roskinproski@gnu.org wrote:
Hello!
The reason OpenBIOS violates the strict aliasing rules so often is because it uses char arrays to represent endian-specific data.
Char arrays may have alignment different from that of the longer types. That's why casting a pointer to such array to a pointer to a longer type and dereferencing it is considered unsafe by the compiler. The compiler assumes that different types would not occupy the same memory unless we tell it not to make such assumption.
Char arrays serve as protection against misusing endian-specific data as host-endian integers. The alternative it to use sparse annotated types, such as __le32. __le32 has the same alignment as u32, but sparse would recognize attempts to use __le32 in arithmetic operations.
I think switching to sparse annotated types would be a good idea whether strict aliasing is disabled or not. It makes the code more readable. It could also fix some hard to find bugs.
Would it be possible and/or useful to use sparse types for cell types?