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 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) = 1This 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? 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
OpenPGP_signature
Description: OpenPGP digital signature