No, you're just not reading carefully.
Go back and look for the words "once the habit has been developed".
I read it just fine. Even once you "develop the habit", it's still
not zero effort to write (or read). And the extra code still
introduces additional potential for bugs.
Code that has cleanly written checks for allocation failures is easier
to read and write than code that constantly makes me ask "What if that
fails?".
Exceptions were invented and are now a popular feature of programming
languages precisely because you're wrong about that. Moving
exceptional condition processing out of the main processing makes the
code more readable.
Leaving out checks for errors GUARANTEES more bugs. I'll take the
additional code and the risk of getting it wrong over the certainty
that the shorter code is wrong, thanks.
Straw man. I never said leaving out checks for allocation failures
was appropriate. I said it was not zero effort. Try to read more
carefully.
It gets less cluttered and ugly if you use a less cluttered and ugly
error handling strategy.
For one thing, trying to back out all of your allocations so far at
every point where one of them can fail blows up pretty quickly when
more than one thing can fail.
To be honest, I'm not pleased with the solution I coded up almost
without thought *or* your solution. I find them both cluttered.
By the way, I'm not trying to accuse you of writing ugly code. What
we're seeing is just the side effect of using a language without
garbage collection or exceptions.
And to be clear, I'm not suggesting C should add garbage collection or
exceptions, either. If you care to use them, languages with those
features already exist. C is good in its niche and shouldn't try to
become one of those other languages.
How many lines of code do the "do some work" comments represent? I bet
it's more than ten or twelve, and quite possibly enough to make ten or
twelve look vanishingly small in comparison.
I don't care. This is completely unrelated to the point I was making.
One line per allocation in the part of the function that does the
interesting bits.
Error recovery code that cleanly backs out the allocations, and can
sometimes be combined with normal cleanup in functions that allocate
resources to work with instead of allocating them for higher-level
functions.
Not exactly a great cognitive burden. If I'm reading that code, the
amount of time I spend on the error recovery will probably be lost in
the noise when you put it up against the time I'll spend wrapping my
brain around how hundreds, thousands, or even tens of thousands of
functions work together.
The fact that it is a cognitive burden is well known, which is why
people experience application failures daily, including but not
limited to:
* Memory or other resource leaks.
* Segmentation faults.
* Bugs caused by wild pointers.
* Malicious input or programs that leverage these common bugs in order
to do "bad things" with your computer *or* to your computer.
But this is all well known, and to deny it is foolishness. It's
exactly why other programming languages are now popular for many
applications for which C was traditionally used.
And when you fill out the "do some work" comments, suddenly you're
comparing something like 362 vs. 337 lines of code, and for some reason
it doesn't look like such a big difference anymore.
If you're trying to simplify it using lines of code as your metric,
leaving out the error handling is Just Not Worth Your Time.
Sometimes, the smallest amount of code can cause the greatest amount
of headaches.
Well, yeah, if all you do is allocate and deallocate resources, using a
language that handle the deallocation for you means you only have to
write half as much code. That should be obvious.
If you actually do something with the resources you allocate, then
suddenly you're writing maybe 5% less code? 10%? 25% if you're doing
something trivial?
The error handling code is going to be some of the easiest bits of that
code to write, because once you've gotten into the habit of doing it,
it practically writes itself.
It might be a small amount of code, but that doesn't mean it's not
very prone to mistakes commonly made by developers.
Checking for and failing cleanly on simple resource allocation errors
instead of aborting the entire program is not exactly what I would call
"non-trivial".
Straw man. I never said aborting on allocation failure was appopriate
for all applications, but it is acceptable for some applications.
[SNIP]
The rest of your post seems to be trying to force me to defend a
stance I never took in the first place, so I'll ignore it.