On Fri, Feb 24, 2023 at 01:02:54AM +0100, Alex Colomar wrote: > Hi Martin, > > On 2/23/23 20:57, Martin Uecker wrote: > > Am Donnerstag, dem 23.02.2023 um 20:23 +0100 schrieb Alex Colomar: > > > Hi Martin, > > > > > > On 2/17/23 14:48, Martin Uecker wrote: > > > > > This new wording doesn't even allow one to use memcmp(3); > > > > > just reading the pointer value, however you do it, is UB. > > > > > > > > memcmp would not use the pointer value but work > > > > on the representation bytes and is still allowed. > > > > > > Hmm, interesting. It's rather unspecified behavior. Still > > > unpredictable: (memcmp(&p, &p, sizeof(p) == 0) might evaluate to true or > > > false randomly; the compiler may compile out the call to memcmp(3), > > > since it knows it won't produce any observable behavior. > > > > > > <https://software.codidact.com/posts/287905> > > > > No, I think several things get mixed up here. > > > > The representation of a pointer that becomes invalid > > does not change. > > > > So (0 === memcmp(&p, &p, sizeof(p)) always > > evaluates to true. > > > > Also in general, an unspecified value is simply unspecified > > but does not change anymore.
Right. p is its own thing - n bytes on the stack containing some value. Once it comes into scope, it doesn't change on its own. And if I do free(p) or o = realloc(p), then the value of p itself - the n bytes on the stack - does not change. I realize C11 appears to have changed that. I fear that in doing so it actually risks increasing the confusion about pointers. IMO it's much easier to reason about o = realloc(p, X); (and more baroque constructions) when keeping in mind that o, p, and the object pointed to by either one are all different things. > > Reading an uninitialized value of automatic storage whose > > address was not taken is undefined behavior, so everything > > is possible afterwards. > > > > An uninitialized variable whose address was taken has a > > representation which can represent an unspecified value > > or a no-value (trap) representation. Reading the > > representation itself is always ok and gives consistent > > results. Reading the variable can be undefined behavior > > iff it is a trap representation, otherwise you get > > the unspecified value which is stored there. > > > > At least this is my reading of the C standard. Compilers > > are not full conformant. > > Does all this imply that the following is well defined behavior (and shall > print what one would expect)? > > free(p); > > (void) &p; // take the address > // or maybe we should (void) memcmp(&p, &p, sizeof(p)); ? > > printf("%p\n", p); // we took previously its address, > // so now it has to hold consistently > // the previous value > > > This feels weird. And a bit of a Schroedinger's pointer. I'm not entirely > convinced, but might be. Again, p is just an n byte variable which happens to have (one hopes) pointed at a previously malloc'd address. And I'd argue that pre-C11, this was not confusing, and would not have felt weird to you. But I am most grateful to you for having brought this to my attention. I may not agree with it and not like it, but it's right there in the spec, so time for me to adjust :) -serge