Nov 8, 2024 09:41:00 Alejandro Colomar <a...@kernel.org>: > 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. >
lol yeah every time I deal with defer in go (and there have been some baroque instances) i have to write some tests to make sure I've got the behavior right. > 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. > > > Have a lovely day! > Alex > > -- > <https://www.alejandro-colomar.es/>