5 ms·
> 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 o
by walki 6y 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 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?
- jart 6y agoNot 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.
- bsder 6y agoHuh. 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?
- murderfs 6y agorestrict 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.
- walki 6y agoOK 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).
- nzentzis 6y agoI think C and C++ have enough problems with accidental undefined behavior already without making aliased pointers into UB.
- dodobirdlord 6y agoLikely most C code, particularly data structure code, would break if compiled with a setting that treats all pointers as restrict.
- walki 6y agoWhat'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.
- Skunkleton 6y ago> 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.