Path: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Lawrence D'Oliveiro Newsgroups: comp.lang.c Subject: Re: Fixing a sample from K&R book using cake static analyser Date: Sat, 22 Jun 2024 23:30:23 -0000 (UTC) Organization: A noiseless patient Spider Lines: 57 Message-ID: References: <20240623022343.ec355c69a3d9eb03ad4a50f2@gmail.moc> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Injection-Date: Sun, 23 Jun 2024 01:30:23 +0200 (CEST) Injection-Info: dont-email.me; posting-host="be24819e5877b282c066214411113658"; logging-data="4188185"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+5lD/qcWfddHMte6UPkGeI" User-Agent: Pan/0.158 (Avdiivka; ) Cancel-Lock: sha1:d6o+VKZONK45OccSu0Xx7KM0XoQ= Bytes: 2800 On Sun, 23 Jun 2024 02:23:43 +0300, Anton Shepelev wrote: > Why are you so afraid of `goto' ... Look up the concept of a “Nassi-Shneiderman diagram”. It allows arbitrary nesting of complex code, with dynamic allocation going on, while minimizing flow-control headaches. The example I posted was a simple one; I have more complex ones if you want to see. > I think you forget to set np->name (and to free() it in > case of error). Ah, didn’t notice that, since it was hidden in the middle of another line of code. The fix is simple. And while I’m at it, it makes sense to factor out the table entry disposal code into a separate routine. void np_free(struct nlist *np) { if (np != NULL) { free(np->name); free(np->defn); } /*if*/ free(np); } /*np_free*/ struct nlist *install(char *name, char *defn) { struct nlist *np = NULL; struct nlist *result = NULL; unsigned hashval; do /*once*/ { result = lookup(name); if (result != NULL) break; np = (struct nlist *)calloc(1, sizeof struct nlist); if (np == NULL) break; np->name = strdup(name); if (np->name == NULL) break; np->defn = strdup(defn); if (np->defn == NULL) break; hashval = hash(name); np->next = hashtab[hashval]; hashtab[hashval] = np; result = np; np = NULL; /* so I don’t dispose of it yet */ } while (false); np_free(np); return result; } /*install*/