Path: ...!weretis.net!feeder9.news.weretis.net!news.quux.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!eternal-september.org!.POSTED!not-for-mail From: Kaz Kylheku <643-408-1753@kylheku.com> Newsgroups: comp.lang.c Subject: Re: So You Think You Can Const? Date: Thu, 9 Jan 2025 04:24:56 -0000 (UTC) Organization: A noiseless patient Spider Lines: 84 Message-ID: <20250108200758.563@kylheku.com> References: <20250107130809.661@kylheku.com> <87a5c15ob0.fsf@bsb.me.uk> <87ldvk4wu7.fsf@bsb.me.uk> Injection-Date: Thu, 09 Jan 2025 05:24:56 +0100 (CET) Injection-Info: dont-email.me; posting-host="701316071098cc7b6fe8181daaf2e5b8"; logging-data="3377394"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX191K5IVLodtzYRR8eTy8Ls+/m+XPxC8jX4=" User-Agent: slrn/pre1.0.4-9 (Linux) Cancel-Lock: sha1:A7RfDRT8F/cOpH81f8OmuokAODQ= Bytes: 3511 On 2025-01-09, Ben Bacarisse wrote: > Julio Di Egidio writes: > >> static AvlTree_t const *AvlTree_node( >> void const *pk, AvlTree_t const *pL, AvlTree_t const *pR >> ) { >> AvlTree_t *pT; >> >> pT = malloc(sizeof(AvlTree_t)); >> >> if (!pT) { >> return NULL; >> } >> >> pT->pk = pk; >> pT->pL = pL; >> pT->pR = pR; >> >> return pT; >> } > > Just on a side issue, I prefer to make tests like this positive so I'd > write: > > static AvlTree_t const *AvlTree_node( > void const *pk, AvlTree_t const *pL, AvlTree_t const *pR > ) { > AvlTree_t *pT = malloc(*pT); > > if (pT) { > pT->pk = pk; > pT->pL = pL; > pT->pR = pR; > } > return pT; > } More generally: foo_handle *foo = foo_create(); bar_handle *bar = foo ? bar_create(foo) : 0; // doesn't like null xyzzy_handle *xyz = xyzzy_create(42, bar, arg); container *con = malloc(sizeof *con); if (foo && bar && xyz && con) { // happy case: we have all three resources con->foo = foo; con->bar = bar; con->xyz = xyz; return con; } xyzzy_destroy(xyz); xyzzy_destroy(bar); if (foo) xyzzy_destroy(foo); // stupidly doesn't like null return 0; > I'm not going to "make a case" for this (though I will if you want!) -- > I just think it helps to see lots of different styles. I might just have made the case. When more resources need to be acquired that might fail, it consolidates the happy case under one conjunctive test, and consolidates the cleanup in the unhappy case. Effectively it's almost if we have only two cases. A minor disadvantage is that in the unhappy flow, we may allocate resources past the point where it is obvious they are not going to be needed: if foo_create() failed, we are pointlessly calling xyzzy_create() and malloc for the container. It's possible that these succeed, and we are just going to turn around and free them. It's a form of consolidated error checking, like when we make several system calls and check them for errors as a batch; e.g. call fprintf several times and check for disk full (etc) just once. -- TXR Programming Language: http://nongnu.org/txr Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal Mastodon: @Kazinator@mstdn.ca