Adjusting to C
tspurway.github.io
tspurway.github.io
Occasionally, the book-keeping to make sure you're able to clean up each allocation individually can be higher than the overhead of garbage collection. Of course, if you're working in C, you can just add garbage collection, either globally (Boehm collector, say, though I don't know how well it actually performs) or only for some particular resources (though then you do need to be sure you are tracking your roots appropriately).
I always find it amusing when I write something that spends a bunch of work making sure everything is freed before it exits. (It's worth doing so valgrind can help you be more confident you're freeing what should be freed as you go along.)
Yeah, just exit! That's the kind of cool thing about these small, short lived Unix programs like grep and cat - chew memory (stack or heap, up to you!) and bail out - let the OS clean it up. It is essentially the same argument as "prefer large mallocs to small" - the process itself is a 'large malloc'.
splint has been useful, but needs c99 (and now c11) support.
Tangential, but one thing I've recently taken to doing in my C is basically avoiding bare primitive types, preferring to wrap them in a single element struct. This means I can't pass, for instance, price where I mean quantity just because they're "both numbers".
At the beginning of my career, I spent fourish years professionally writing K&R C. Before that I had convinced my profs that I could submit my assignments in C rather than the mainframe Pascal that was being used by the other students. The balance has been spent in Smalltalk, Java, Python, etc.
I must say that I really like the re-adjustment. Even though there are 'endless banks of RAM', C forces the programmer to be stingy with memory and come up with neat hacks, simply to avoid the enormous pain of being too clever.
Using malloc() is like lying. You've got to remember them all.
The article was more about: Python programmer meets C, C introduces him to malloc(), programmer falls in love with malloc, C gets jealous and in a fit of rage deallocates programmer.
I think this extended love affair for C comes from the fact that it's the least-common-denominator in terms of what our OSes are written in. At some point everything has to make system calls that are using C calling conventions and data structures. It makes sense that the base layer of everything will be written in C. It's an historic anomaly, not some fundamental awesomeness of the language itself.
That said, it's a fundamentally awesome language, especially to build OSes in, but that's tangential.
C11 4 [conformance]/p6 "A conforming freestanding implementation shall accept any strictly conforming program in which the use of the features specified in the library clause (clause 7) is confined to the contents of the standard headers <float.h>, <iso646.h>, <limits.h>, <stdalign.h>, <stdarg.h>, <stdbool.h>, <stddef.h>, <stdint.h>, and <stdnoreturn.h>." [2]
[1] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n324... [2] http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
I've seen this thought hundreds of times over the last decade, and I don't think it's a very good one. If execution environment A is twice as fast as B, it will still be twice as fast after the processor speed doubles. Mostly, we usually want to do as much as we can with the hardware we have.
It's speed.
It is also almost always interesting. It reveals a boundary that has been crossed, a bottleneck plugged. I think that us HLL devs always like to think we have C in our back pockets. We say, "well if performance is bad we will profile then rewrite that bit in C". Then, when faced with the reality of actually having to write something in C, well it's a different story. We think the performance increase will be dramatic, but often we are left with something that performs worse than the original HLL equivalent, and that leaks memory and frequently crashes to add insult to injury!