News for hackers. Stuff that matters.
Re:C pointers are not hardware pointers by skissane on Sunday March 06, 2016 @04:54PM (#11235728)
Imagine the following possible architecture: every pointer contains a valid bit (V), which is initially set to 1. The V bit is checked on every pointer dereference, and dereferencing a pointer with V=0 traps. free(p) as well as freeing the memory pointed to by p, also sets p.V=0. Now, if you copied p earlier, the copy would still have V=1, and hence would now != the original pointer, even though the actual address stored inside the pointer is the same. So your sample code would end up doing a double free on p when foo is false.

We can question whether the design choices of such a CPU architecture are sensible or not, but I can certainly imagine such a design decision being made at some point in the last few decades. Indeed, if you look at the history of tagged memory architectures (e.g. Burroughs large systems, IBM System/38, Intel iAPX 432) - their tagged pointers are in the same spirit as what I've described here, except they used multiple bits instead of just one, and the tag bits were often stored in a distinct memory area from the actual pointer addresses (I don't know how C implementations on those platforms - if they existed - actually handled free() or pointer comparison though.) I guess, the possibility of such a design decision motivates making this undefined behaviour in the C standard.

Re:C pointers are not hardware pointers by dllthomas on Monday March 07, 2016 @12:39AM (#11237323)
Except that free is defined to be a function, so it can't really make changes to arguments passed by value.
Re:C pointers are not hardware pointers by skissane on Monday March 07, 2016 @06:25AM (#11238294)
In general you are correct that C function arguments are passed by value. However, in the case of free() specifically, an implementation which treated the argument of free() as if it were passed by reference would be conforming. Obviously one cannot write a free() implementation in standard C with this behaviour, but there is no requirement that a conforming implementation's standard library functions such as free() have to be written in standard C (or indeed in C at all.)

As rm445 quoted C11 clause 6.2.4 para 2, "The value of a pointer becomes indeterminate when the object it points to (or just past) reaches the end of its lifetime". Hence, prior to free(p), p had a determinate value, now it has an indeterminate value. The standard imposes no requirement that it has the same value as it had before (indeed, such a requirement would contradict the explicit statement that the value is now indeterminate.) Any reliance on p having some particular value post free(p) is relying on undefined behaviour, and in undefined behaviour one is allowed to do anything at all, including giving free(p) pass-by-reference argument handling.

Re:C pointers are not hardware pointers by dllthomas on Tuesday March 08, 2016 @12:44AM (#11243736)
While I'm not sure there's no language preventing call-by-reference semantics around the pointer value, I agree that you could not distinguish without invoking undefined behavior, so it probably doesn't matter any.

Interestingly, the free() might poison not only the pointer passed in but all identical pointers as well.

This seems to allow us to implement pointers with two hops - the bits stored in a pointer value indexing into a lookup table that contains the actual address of the object. In that case, free could manipulate that table, invalidating existing pointers.