Am Freitag, dem 08.11.2024 um 16:40 +0100 schrieb Alejandro Colomar via Gcc:
> Hi JeanHeyd,
>
> I was involved this week in a fix for a bug I wrote some months ago
> about a call to free(3) with a bad pointer.
>
> The simplest reproducer is:
>
> $ cat strsep_bad.c
> #include <string.h>
> #include <stdio.h>
> #include <stdlib.h>
>
> int
> main(void)
> {
> char *p;
>
> p = strdup("123;");
> strsep(&p, ";");
> free(p);
>
> puts("done");
> }
>
> $ cc -Wall -Wextra strsep.c
> $ ./a.out
> free(): invalid pointer
> Aborted
>
> A fix for that program is to store a copy of the original pointer:
>
> $ cat strsep_good.c
> #include <string.h>
> #include <stdio.h>
> #include <stdlib.h>
>
> int
> main(void)
> {
> char *p, *dup;
>
> p = dup = strdup("123;");
> strsep(&p, ";");
> free(dup);
>
> puts("done");
> }
>
> While I could sympathize with 'defer', I'm wondering if it may simplify
> some code avoiding goto's, at the expense of being obscurely dangerous
> in other cases like this one. I suspect one could blindly attempt to do
> the following:
>
> $ cat strsep_bad_defer.c
> #include <string.h>
> #include <stdio.h>
> #include <stdlib.h>
>
> int
> main(void)
> {
> char *p;
>
> p = strdup("123;");
> defer free(p);
>
> strsep(&p, ";");
>
> printf("done");
> }
>
> Since 'p' in free(p) is evaluated after strsep(3), it is equivalent to
> the first program, which is bogus. I think goto better codifies the
> evaluation order, and allows the programmer to think about what it's
> doing.
>
> So defer would only be good for the common case, which is usually
> simple-enough that goto should be enough. And it's bad in those corner
> cases where you really to be careful. I think I've changed my mind
> about defer to not want it.
>
> I wanted to have this thought written in a mailing list to be able to
> reference it.
When we wrote the original proposal for C23 Robert had a collection
of code examples before and after rewriting to use defer. At that
time I somewhat lost a bit of interest in the feature ;-) But many
people seem to like it. I think it would be useful to revisit
these (and more) realistic code examples to get some clarity.
Martin