4 ms·
In a project I'm working on[0], there's an array object type used throughout, which can sometimes point to arbitrary data elsewhere. In a funky edge-case[1], su
by dzaima 3y ago
In a project I'm working on[0], there's an array object type used throughout, which can sometimes point to arbitrary data elsewhere. In a funky edge-case[1], such an array can be built with an unaligned data pointer.
Thus, if gcc/clang started seriously utilizing aligned pointer accesses everywhere, nearly every single load & store in the entire project would have to be replaced with something significantly more verbose. Maybe in a more fancy language you could have ptr<int> vs unaligned_ptr<int> or similar, but in C you kinda just have compiler flags, and maybe __attribute__-s if you can spare some verbosity.
C UB is often genuinely useful, but imo having an opt-out option for certain things is, regardless, a very reasonable request.
[0]: https://github.com/dzaima/CBQN https://github.com/dzaima/CBQN
[1]: Any regularly allocated array has appropriate alignment. But there are some functions that take a slice of the array "virtually" (i.e. pointing to it instead of copying), and another one that bitwise-reinterprets an array to one with a different element type (again, operating virtually). This leads to a problem when e.g. taking i8 elements [3;7) and reinterpreting as an i32 array. A workaround would be to make the reinterpret copy memory if necessary (and this would have to be done if targeting something without unaligned load/store), but that'd ruin it being a nice O(1).
- lights0123 3y ago> in C you kinda just have compiler flags, and maybe __attribute__-s if you can spare some verbosity Which you can use to wrap the unaligned type as a packed struct, i.e. struct __attribute__((__packed__)) unaligned_int { int i; }; which has an alignment of 1.
- tylerhou 3y ago> This leads to a problem when e.g. taking i8 elements [3;7) and reinterpreting as an i32 array. Even ignoring alignment issues, this is already UB because it violates the strict aliasing rule. You technically need to memcpy and hope that the compiler optimizes the memcpy out. In C++20 you can use std::bit_cast in some circumstances. https://en.cppreference.com/w/cpp/numeric/bit_cast https://en.cppreference.com/w/cpp/numeric/bit_cast. In C11 you can use a union, but that still requires a "copy" into the union.
- dzaima 3y agoI'm of course already using -fno-strict-aliasing (primarily because without it it's impossible to implement a custom memory allocator, but it also helps here).