14

Both GCC and Clang can switch off the braindead type-based aliasing rules through the "-fno-strict-aliasing" compiler option so that everything can alias everything.

On the other hand, C offers the "restrict" qualifier for pointers where you promise that nothing will alias this memory area, not even same type pointers.

What happens if you use "restrict", but compile with "-fno-strict-aliasing"? Will the "restrict" be obeyed or disregarded?

Answer in the comments.

Comments
  • 6
    As tested with Godbolt and looking at the disassembly, both compilers will obey the "restrict". It seems to enjoy priority over "-fno-strict-aliasing".

    That's super because you can switch off the aliasing rules and still reap the performance where it actually matters.

    That has always been code with same-type aliasing such as matrix operations where type-based aliasing cannot work, which is why it's braindead to begin with.
  • 7
    Ha the joke is on you bro! I don't know what any of this means!
  • 0
    Only thing i don't know about here is Godbolt, so instead of googling it, what is it?
  • 7
    @arcsector A compiler explorer. You put in some code, select which language it is in (not just C/C++), which compiler you want, which version, which target, which compiler options.

    Presto, you get the disassembly of the resulting machine code. Super nice to see what shit will actually compile to.

    https://godbolt.org
  • 2
    When you disable compiler errors/optimisations because undefined behaviour is the behaviour you want
  • 2
    @electrineer If you disable the type based aliasing, the behaviour isn't undefined. The Linux kernel is full of that.

    Remember Torvalds' rant when GCC made strict aliasing the default and shit stopped working because the kernel team hadn't read the compiler release notes?

    I recommend using strict aliasing and the associated warning for debug builds, but disabling it for releases unless you get measurable and significant performance benefits out of that - which you won't see in most cases.

    But even if so, that's probably just because you havn't put "restrict" where it would have made sense.
  • 3
    Another helpful idiom I often use is not operating on pointer contents directly, but reading that into a local variable with the smallest scope possible, working on that, and then storing it back. That makes it clear to the compiler that it can use a register here regardless of any pointer aliasing.

    It also works in interrupts for volatile variables (for sharing between interrupt and application) that cannot change unexpectedly because the application doesn't run while the interrupt is being serviced. The compiler however cannot know this and has to fetch volatile variables upon every access.
  • 1
    @AleCx04 unironically, ignorance(or well developed abstraction) is bliss in this profession.
Add Comment