On Fri, Feb 24, 2023 at 02:42:32AM +0100, Alex Colomar wrote: > Hi Serge, Martin, > > On 2/24/23 02:21, Serge E. Hallyn wrote: > > > 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 :) > > I'll try to show why this feels weird to me (even in C89): > > > alx@dell7760:~/tmp$ cat pointers.c > #include <stdio.h> > #include <stdlib.h> > > > int > main(void) > { > char *p, *q; > > p = malloc(42); > if (p == NULL) > exit(1); > > q = realloc(p, 42); > if (q == NULL) > exit(1); > > (void) &p; // If we remove this, we get -Wuse-after-free
(which I would argue is a bug in the compiler) > printf("(%p == %p) = %i\n", p, q, (p == q)); > } > alx@dell7760:~/tmp$ cc -Wall -Wextra pointers.c -Wuse-after-free=3 > alx@dell7760:~/tmp$ ./a.out > (0x5642cd9022a0 == 0x5642cd9022a0) = 1 > > > This pointers point to different objects (actually, one of them doesn't even > point to an object anymore), so they can't compare equal, according to both: > > <http://port70.net/%7Ensz/c/c11/n1570.html#6.5.9p6> > > <http://port70.net/~nsz/c/c89/c89-draft.html#3.3.9> > > (I believe C89 already had the concept of lifetime well defined as it is > now, so the object had finished it's lifetime after realloc(3)). > > How can we justify that true, if the pointer don't point to the same object? Because what's pointed to does not matter. You are comparing the memory address p, not the contents of the memory address. By way of analogy, if I do mkdir -p /tmp/1/a ln -s /tmp/1 /tmp/2 rm -rf /tmp/1 then /tmp/2 is still a symlink. 'stat /tmp/2' still works and is well defined. And if I create a new /tmp/1, then /tmp/2 starts pointing to that. Yes, re-useing p like that is a very bad idea, in many cases :) > And how can we justify a hypothetical false (which compilers don't > implement), if compilers will really just read the value? To implement this > as well defined behavior, it could result in no other than false, and it > would require heavy overhead for the compilers to detect that the > seemingly-equal values are indeed different, don't you think? The easiest > solution is for the standard to just declare this outlaw, IMO. > > Maybe it could do an exception for printing, that is, reading a pointer is > not a problem in itself, a long as you don't compare it, but I'm not such an > expert about this. > > Cheers, > > Alex > > > > > -serge > > -- > <http://www.alejandro-colomar.es/> > GPG key fingerprint: A9348594CE31283A826FBDD8D57633D441E25BB5 >