4 ms·
The biggest failure of this article is the multiple admonishments "never do <blah> (except for this, this, and that other case over there" - all advice of this
by hyc_symas 11y ago
The biggest failure of this article is the multiple admonishments "never do <blah> (except for this, this, and that other case over there" - all advice of this form is worthless when your supposed thesis is making code readable and consistent.
Consistency means avoiding special cases. Variable length arrays are too prone to special cases - IMO, just don't use them. malloc vs calloc is too prone to special cases, that rule is worthless. The rule "never use memset" is full of special cases, also worthless. (And in fact, for your larger automatic initializations, gcc just generates code to call memset anyway.) I would say "always use memset when you need zeroing - then you'll never be surprised." The fewer special cases you have to keep track of, the better.
"Never cast arguments to printf - oh but for %p, always cast your pointers to (void *)" again, worthless advice with an unacknowledged special case.
The way to write code that always works right is to always use consistent methodology and avoid any mechanism that is rife with special cases.
The advice "always return 'true' or 'false' instead of numeric result codes" is worthless. Functions should always return explicit numeric result codes with explicitly spelled out meanings. enum is nice for this purpose because the code name is preserved in debug builds, saves you time when working inside a debugger. But most of all, it's a waste of time for a function to return a generic false/fail value which then requires you to take some other action to discover the specific failure reason. POSIX errno and Windows GetLastError() are both examples of stupid API design. (Of course, even this rule has an exception - if the function cannot fail, then just make it return void.)