If I may add my thoughts here, On Thursday, February 23rd, 2023 at 20:42, Alex Colomar wrote: > 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 > > 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:
In this case p and q both _do_ point to the same object, which is valid. As per [https://port70.net/~nsz/c/c11/n1570.html#3.15], if the pointers both refer to the same storage region *[1] then they, by definition, refer to the same object and so should compare as true. This equality is entirely up to the implementation of your libc's realloc and cannot be depended upon, so the warning is absolutely warranted *[2]. I don't believe that it's correct for gcc to do more based off of external implementation-defined behavior. *[1]: Which may or may not need to be sized. I'm not an expert at reading specs, and besides, in this case the pointer is of the same type and value. This point seems more related to aliasing rules than lifetimes. *[2]: There are, however, genuine cases where the reuse could be valid. Namely that if q is null, then p is guaranteed to still point to a valid allocation. Fortunately, I can't get gcc to trigger a false warning in this case. > > http://port70.net/~nsz/c/c11/n1570.html#6.5.9p6 > > > http://port70.net/~nsz/c/c89/c89-draft.html#3.3.9 Just to be transparent, I'm working exclusively off of the first link. Also, this is just a passing interpretation of the c11 spec. > > > (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? 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. Again, this is an issue with defining an object. > 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. One last thought: with the above strict interpretation of the c standard, it would become nigh on impossible to implement the malloc(3) family of functions in c themselves. I vote for the "shared storage" interpretation of the c11 standard that is actually implemented rather than this abstract liveness oriented interpretation. -- Cheers, Peter Lafreniere <n8pjl.ca> "Who malloc()'s for malloc()?" - Myself, 2023-02-24