13 comments

  • afdbcreid a day ago ago

    Ralf Jung's series (one of the prominent developers behind Rust's memory model and author of RustBelt) about pointers is very recommended:

    https://www.ralfj.de/blog/2018/07/24/pointers-and-bytes.html

    https://www.ralfj.de/blog/2020/12/14/provenance.html

    https://www.ralfj.de/blog/2022/04/11/provenance-exposed.html

  • jayd16 a day ago ago

    Does C++ pointer arithmetic invalidate this post or is there some other magic there?

    • jcranmer a day ago ago

      To make a long story short:

      Pointer provenance is not explicitly present in the C standard. There is a TS, TS 6010, that introduces a pointer provenance model that is fairly close to the effective model of most compilers. Prior to that discussion, compilers have documented a vague model of "pointers need to be based on their original address," but these vague models are usually poorly upheld by the actual compiler [1].

      C++ inherits C's failure to discuss pointer provenance, and tacks on an additional complication that it tries to reason about the value of pointers to objects outside their lifetimes. The current thinking on the C++ committee is to give up and go with an "angelic nondeterminism" model, i.e., if there is some possible way to give the program well-defined semantics, that is the semantics of the program. (See https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2026/p24... for the current proposal).

      [1] In more detail, the principal problem is pointer <-> integer conversions. The compiler is usually thinking of provenance in terms of escaping pointers--there is a use or a source that the compiler cannot definitively track down--and converting a pointer to an integer is an operation that causes the pointer to escape. But the compiler also tends to optimize integers in a way that doesn't preserve provenance (i.e., if x == y, the compiler will freely rewrite a use of x to a use of y or vice versa, even though the two need not have the same provenance!), and also also, a conversion of a pointer to an integer may be dropped if the result is unused. This makes it fairly easy to write programs that are miscompiled under sane provenance models.

      • WalterBright a day ago ago

        D does not allow conversion of an int to a pointer in code marked @safe.

      • uecker a day ago ago

        Have they ever clarified the semantic ambiguities that arise when mixing demonic and angelic nondeterminism?

        • DarkNova6 a day ago ago

          Yes, you get nasal demons.

          • uecker a day ago ago

            Well this depends on which supernatural being wins the game.

        • jcranmer a day ago ago

          It's WG21, so no.

    • Sharlin a day ago ago

      Neither C nor C++ allows you to derive pointers pointing outside the original object (as in, memory allocation), it's UB. Yes, the arithmetic operation itself has UB, not merely later derefering an OoB pointer. The only exception is one-past-the-end pointers which are safe to create (but not to dereference of course).

      Whether it's safe to "smuggle" pointers around as ints, without doing any arithmetic on them, is "complicated" and honestly there's no one single answer as far as I know.

      • adgjlsfhk1 20 hours ago ago

        The other really complicated part is that it is very common to have intermediary ints that have very little relation to the ptr that they come from/turn into (e.g. XOR linked lists are probably legal even though they have ints that mix provenance of 2 completely separate pointers).

    • adgjlsfhk1 a day ago ago

      C++ memory provenience is very complicated (and possibly unsound) because it lets you do all sorts of complicated things like this.

  • uecker a day ago ago

    As far as I know, provenance is still a mess both on LLVM and GCC.

  • zkxjzmswkwl1 a day ago ago

    ok but like

        int** justanint = *(int**)(some_pointer);