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