Hacker News new | ask | show | jobs
by walki 1989 days ago
> C compilers have to assume that pointers to memory locations can overlap, unless you mark them __restrict...

What I don't fully understand is: "GCC has the option -fstrict-aliasing which enables aliasing optimizations globally and expects you to ensure that nothing gets illegally aliased. This optimization is enabled for -O2 and -O3 I believe." (source: https://stackoverflow.com/a/7298596)

Doesn't this mean that C++ programs compiled in release mode behave as if all pointers are marked with __restrict?

2 comments

restrict and strict aliasing have to do with the same general concept, but aren't the same. They both have to do with allowing the compiler to optimize around assuming that writes to one pointer won't be visible while reading from another. As a concrete example, can the following branches be merged?

  void foo(/*restrict*/ bool* x, int* y) {
    if (*x) {
      printf("foo\n");
      *y = 0;
    }
    if (*x) {
      printf("bar\n");
    }
  }
Enabling strict aliasing is effectively an assertion that pointers of incompatible types will never point to the same data, so a write to y will never touch *x. restrict is an assertion to the compiler on that specific pointer that no other pointer aliases to it.
OK thanks, indeed Clang is able to generate better assembly using __restrict__. And -O3 generates the same assembly as -O3 -fstrict-aliasing (which is not as good as __restrict__).

I wish there was a C/C++ compiler flag for treating all pointers as __restrict__. However I guess that C/C++ standard libraries wouldn't work with this compiler option (and therefore this compiler option wouldn't be useful in practice).

What's interesting to note though is that I tried marking pointers __restrict__ in the performance critical sections in 2 of my C++ projects and the assembly generated by Clang was identical in all cases!

So while it is true that by default Rust has a theoretical performance advantage (compared to C/C++) because it forbids aliasing pointers I wonder (doubt) whether this will cause Rust binaries to generally run faster than C/C++ binaries.

On the other hand Rust puts security first, so there are lots of array bounds checks in Rust programs (and not all of these bounds checks can be eliminated). Personally I think this feature deteriorates the performance of Rust programs much more than you gain by forbidding aliasing pointers.

> so there are lots of array bounds checks in Rust programs

Depends on how those programs were written. Iterators should avoid bounds checking for example.

Likely most C code, particularly data structure code, would break if compiled with a setting that treats all pointers as restrict.
I think C and C++ have enough problems with accidental undefined behavior already without making aliased pointers into UB.
Not for char. Compiler always assumes non-restrict for char pointers and arrays, which is important to remember if you're ever operating on a RGB or YCbCr matrix or something.
Huh.

Does that also hold for a "uint8_t"--which is often just a renamed unsigned char rather than being a genuine type of its own?

not according to the standard, but in practice yes, currently. there are arguments that it should be considered not for optimization reasons, but there is likely too much existing code relying on it to change behavior. (see related llvm, gcc bugs)
Yes