Sujet : Re: So You Think You Can Const?
De : david.brown (at) *nospam* hesbynett.no (David Brown)
Groupes : comp.lang.cDate : 13. Jan 2025, 09:58:42
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <vm2kk2$1n8gc$1@dont-email.me>
References : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
User-Agent : Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.11.0
On 13/01/2025 04:10, James Kuyper wrote:
On 1/9/25 21:51, Julio Di Egidio wrote:
On 10/01/2025 03:14, Julio Di Egidio wrote:
...
Julio Di Egidio <julio@diegidio.name> writes:
>
On 09/01/2025 02:09, Ben Bacarisse wrote:
>
Julio Di Egidio <julio@diegidio.name> writes:
...
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;
}
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.
>
That is *more* error prone,
...
... check the return value as soon as the function returns a possibly
null pointer or an error value is certainly more widely applicable,
and quite less error prone, especially if it's
>
I meant: immediately check the return value and bail out if needed.
The other approach does not even simplify on the clean-up, by the way...
The code you're criticizing as more error prone does check the return
value as soon as the function returns, and bails out if needed. It just
bails out through the missing else clause rather than from the if-clause.
It does requires code to be indented farther than the other approach. I
have avoided writing code like that for that reason, particularly when
there's a lot of code inside the it statement's controlled blocks -but
not because it's error prone.
I'm wary of assuming a particular interpretation of what someone else wrote, but I would say there is a valid argument for say that the second style of code is more "error prone".
To me, the phrase "error prone" in regard to a coding style, rather than a piece of code, means that it is more likely that there will be errors (actual code errors, or misunderstandings by other programmers reading the code) written in that style compared to using a different style.
For a short function like this, it's fairly easy to see that there are no errors. In a longer function, perhaps with multiple allocations, the risk is higher.
When you use the "early bail out" form:
if (!pt) return NULL;
there are three key points. One is that the error handling is done at the same point in the code that the error could occur - right after the "malloc". Secondly, the error handling is explicit - it is not left for the reader to realise it is an implicit default result. Thirdly, the return of "NULL" rather than "pt" (known to be null at that point), makes the error situation stand out more clearly, and it is also easier to change it to a different error return value if appropriate.
You can of course also argue that it is best to have the code ordered according to the normal flow of operations - error handling in the middle of the normal code flow can make it hard to follow the algorithm of a function. (C++ exceptions are an extreme version of this.) Some people might prefer a compromise:
static AvlTree_t const *AvlTree_node(
void const *pk, AvlTree_t const *pL, AvlTree_t const *pR
) {
AvlTree_t *pT = malloc(*pT);
if (pT) {
// Normal case
pT->pk = pk;
pT->pL = pL;
pT->pR = pR;
return pT;
} else {
// Error case - malloc failed
return NULL;
}
}
Different styles have different pros and cons, and different balances of emphasis. (They can also have different efficiencies in the normal and error cases, but that's usually less important.)