Earlier quoted context omitted.
And I agree, with an UB the original code is undefined and so any optimization is not right nor wrong, simply keep that UB. But then, why such a long article for a code whose second line is a UB ('p+1' is undefined)?
uintptr_t ip = (uintptr_t)(p+1); Is perfectly defined. What is undefined is converting ip back to a pointer and writing to it, which the original program never does.
Pointers Are Complicated II, or: We need better language specs
41–50 of 135 posts
Re: Pointers Are Complicated II, or: We need better language specs
#42[1] https://en.cppreference.com/w/cpp/memory/gc/pointer_safety
Re: Pointers Are Complicated II, or: We need better language specs
#43First of all: fantastic article . In-depth, insightful, and the examples are absolutely top-notch. On the razor's edge between accessible and profound. Hats off to the author. I will say that the problems seem to lie in a few interesting interlanguage quirks, and not so much on language specs . For example, LLVM and C have different definitions of "undefined behavior"[1] -- this is pointed out when looking at the `po…
Unless we define provenance to only work within certain easy-to-calculate boundaries. But for the general case, sure, just don't optimize when there's uncertainty.
Re: Pointers Are Complicated II, or: We need better language specs
#44Re: Pointers Are Complicated II, or: We need better language specs
#45Earlier quoted context omitted.
As usual; if a compiler knows about undefined behavior I would much rather it throw an error rather than optimize something the programmer didn't intend based on the compiler out-smarting a human's ability to be specific.
It would sometimes work but I think this (very common comment) misses the general point, there's absolutely fine and non buggy on warning-worthy code that can be optimized away if the compiler relies on UB. A very simple example: void do_stuff(int *some_ptr) { do_substuff(some_ptr); *some_ptr += 2; } static void do_substuff(int *some_ptr) { if (some_ptr != NULL) { *some_ptr = 10; } } do_stuff calls a subroutine that…
Re: Pointers Are Complicated II, or: We need better language specs
#46Earlier quoted context omitted.
They are not always integers. See this comment from the previous discussions on the other posts, for example: https://news.ycombinator.com/item?id=17607595
> What happens when 'a' is allocated to a CPU register? When the & operator is used on 'a' it should mark it as unsafe to place the 'a' on a CPU register - CPU allocation is an optimization and optimizations should never affect how the program behaves (except making it run faster, of course) and as such they should only be applied when the compiler can be sure that they're safe to do so. (and yes, the same applies on…
> If 'b' never escapes and no (undefined) pointer arithmetic is used
part.
Re: Pointers Are Complicated II, or: We need better language specs
#47> However, to make the argument that an optimization is correct, the exact semantics of LLVM IR (what the behavior of all possible programs is and when they have UB) needs to be documented. This is a great point as to why formal semantics of programming languages matters. Even if an optimization seems "obviously" correct, finicky things like introducing the possibility of UB can, as the post outlines, cascade into co…
Re: Pointers Are Complicated II, or: We need better language specs
#48If you enjoyed learning about pointer provenance (called "safely-derived pointer" in C++ [1]), you might find the recent addition of std::launder() [2] interesting. [1] https://en.cppreference.com/w/cpp/memory/gc/pointer_safety [2] https://en.cppreference.com/w/cpp/utility/launder
[1] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p218...
Re: Pointers Are Complicated II, or: We need better language specs
#49Earlier quoted context omitted.
uintptr_t ip = (uintptr_t)(p+1); Is perfectly defined. What is undefined is converting ip back to a pointer and writing to it, which the original program never does.
Hmm, I think I understand now. So now I think it's the first optimization the one that is wrong. If you replace a variable with another, don't you need to keep information of the original variable? I mean, if a==b and you do *a=1 you can replace it with *b=1, but then you need to keep the information that 'a' was written to, so other optimizations (the third one) don't think it wasn't. Or am I missing something else…
Note that ip and iq are integers. If you can't replace integers freely, it makes it really hard to optimize arithmetic.
Re: Pointers Are Complicated II, or: We need better language specs
#50Does this have implications about the safety guarantees even safe Rust can make? It seems like incorrect optimization passes could result in bugs/security issues that are a byproduct of the compiler rather than the language itself. I wonder how big of an issue this is for Rust (relatively probably a bigger issue than for C/C++ where basic resource ownership bugs are more common).
So, I mean, if you're arguing that C/C++ programmers are culturally less repulsed by bugs... you might be right about that. Other than that I think it's about the same scale for C/C++ and rust - a bug is a bug no matter what language you wrote it in.
The only fundamental implications I think it has is that maybe we need to put more of an emphasis on formalizing the memory model if we want to reduce the number of soundness bugs (something that a number of people are already doing some awesome work towards).