Octocontrabass wrote:
I'm pretty sure the GCC developers would tell you that's a Linux bug. I don't know if the Linux developers care, though.
In my understanding, the -fno-strict-aliasing option has been added exactly to support such code.
I mean, of course "strict aliasing" != "unaligned access" but this option prevents GCC and Clang to
make a whole set of assumptions like that might potentially turn unaligned access into UB.
Therefore, with -fno-strict-aliasing I believe it's
guaranteed that unaligned access is not UB. There
are several people involved both in GCC and in Linux's kernel, so I'm confident that such code
is not buggy.
In general, I have the perception that the whole strict aliasing thing (somehow related with unaligned access & friends)
is controversial and the fact that modern compilers started to enforce it, made unsafe a ton of old-school C code.
I did a little research about the topic, because I was curious.
1. An interesting essay by Dennis Ritchie back in 1988 about the proposal of "
noalias" which was a stronger version
of modern's
restrict keyword:
http://www.lysator.liu.se/c/dmr-on-noalias.html Obviously,
it's not the same
as
restrict, but it's interesting to read about DMR's general concerns about the topic.
2. A question about the safety of type-punning with unions where the author concludes that
"semantics here is not completely clear".
http://www.open-std.org/jtc1/sc22/wg14/ ... 22.htm#TOC
3. Linus Torvalds ranting about a patch where type-punning with unions are replaced with something else:
https://lkml.org/lkml/2018/6/5/769
4. A blogger ranting against strict aliasing, making some interesting examples:
https://blog.regehr.org/archives/1307
I'm not trying to prove anything other than the topic is
controversial, no matter which part won in the C standard.
At the end, I personally understand both the sides. Just, for kernel development I'd say that probably is more convenient
to not follow strictly the C standard. In particular, about the strict aliasing, I've understood that the biggest reason for
enforcing it was to allow compilers to do auto-vectorization in more cases, but that doesn't apply to kernel code as there,
in 99.99% of the code, we don't allow FPU instructions anyway (because we don't want to save the FPU context etc.).
Another thing, completely unrelated with strict aliasing/unaligned access, but in topic with the problem of following or not
the C standard while writing a kernel is the lack of inline assembly support in the C language. In kernel development, I believe
it's essential and cannot be replaced by separated assembly files, unless we pay the price of function calls, which is not fine
in some cases. I totally understand why inline assembly is not part of the C standard: it's extremely hard or practically impossible
to define it in a generic, arch-agnostic way. All of that, makes perfect sense to me, but it won't stop me from not using inline assembly.
It's simply too convenient. Therefore, we write operating systems either for the C dialect offered by GCC+Clang compilers (very compatible),
or for the C dialect offered by Microsoft VC compiler or for the C dialect offered by the Intel C compiler. In any case, since the C standard
alone it's not just enough for kernel code and we have to live with that, I think it's fine bending some other minor rules here and there if that
will make our lives easier