
The Ten Commandments for C Programmers (1987) - ingve
https://www.lysator.liu.se/c/ten-commandments.html
======
microtherion
This should probably carry a date stamp; my guess would be that it dates from
1990 or so.

Most of the advice is still good, but I would object to (3):

* Excessive casting can be a problem in itself, as it hides genuine type errors (e.g. you think you're casting an int to long, but in reality the variable is a pointer)

* Casting NULL is pointless, as it's already defined by the standard to be a pointer constant, compatible with all data pointers.

* Much of the language about "prototypes" (a.k.a. standard C) was justified at the time, but no longer reflects reality nowadays. It would have to be a very exotic platform that still uses a pre-ANSI C compiler.

~~~
eMSF
>* Casting NULL is pointless, as it's already defined by the standard to be a
pointer constant, compatible with all data pointers.

You should still cast NULL when passed as an unnamed argument to a variadic
function. While NULL is defined to be a null pointer constant, that doesn't
mean it has a pointer type (all integer literals with a value of zero are null
pointer constants in C, but they have an integer type).

(Strictly speaking, all unnamed pointer arguments to variadic functions should
be converted to a compatible pointer type that the variadic function expects.
For example, the printf-line of functions expect a pointer-to-void argument
for a conversion specifier %p. If you pass a pointer-to-int instead,
technically the behaviour is undefined.)

(To whom it may concern: I would appreciate at least a rebuttal. It's not like
this is a subjective matter.)

~~~
monocasa
It's unfortunate that you're getting downvoted; there's for sure real dragons
at the intersection of the NULL literal and variadic functions since it's
totally legal for NULL to be defined as such:

    
    
      #define NULL 0

~~~
a1369209993
Much, much more subtly nasty, it's also legal for NULL to be defined as:

    
    
      #define NULL ((void*)0)
    

and then passed to a function that expects variadic int* parameters on a
machine where register-sized addresses are word-aligned and thus int* has a
different sizeof (and/or bit-level representation) than void*.

------
rgoulter
> if thou thinkest ``it cannot happen to me'', the gods shall surely punish
> thee for thy arrogance

This one is a universal experience. :)

~~~
LargoLasskhyfv
Hmhrhm... _If thou aren 't abide by them, my wrath follows, and make it go
BAM!_

edit: _...my wrath follows, and it shall go BAM!_

------
asveikau
#3 sounds extremely obsolete. I don't completely understand what they mean,
but perhaps they are thinking pre-C89, when it wasn't as common to list the
args in function declarations, so the compiler could not always correctly
convert the type?

I remember in the 90s some libraries (like X11 headers) would put the types of
function arguments inside an ifdef to be able to compile in some archaic
place.

Edit: or maybe they are thinking of varargs. This could still be an issue with
printf today.

------
ape4
I get why they are using King James language but a button to translate to
modern English would help.

~~~
zodiac
It's not even correct - "thy arrogance" should be "thine arrogance"

~~~
matvore
when thou least expect it.

Should be “when thou expectest it least”

lest thou tear thy hair

Should be “lest thou tearest thine hair” as I seem to recall the h sound
acting like vowel for words that sound different based on what follow them.

lest grievous harm befall thy program.

Should be “befalleth”

~~~
all2
Too bad you can't "requesteth a pull" to update the language a bit.

~~~
yesenadam
I believe "-eth" is a 3rd person ending (he/she/it), e.g. _If thy header files
fail_ should be "faileth".

"The third person sing. Present, ending in _th_ , as _taketh_ , _bringeth_ &c.
is now confined to sermons and grave discourse." \- John Hunter, _Text-book of
English Grammar_ 1848

My favourite _-eth_ , from the start of _Moonlighting_ 's Atomic Shakespeare
episode:

 _Good morrow, sir. I 'm Lucentio, come hither for to see fair Padua, pleasant
garden of great Italy, to seek out and happily begin a course of learning and
studies herein._

 _You 've mistaken me, sir, for someone who careth._

[https://youtu.be/ijUr6p8xSBM?t=140](https://youtu.be/ijUr6p8xSBM?t=140)

------
smitty1e
The DMR link => [http://cm.bell-labs.co/who/dmr/](http://cm.bell-
labs.co/who/dmr/)

------
einpoklum
The C++ "equivalent" of this are the "C++ Core Guidelines", which, like the
language itself, are a couple of orders of magnitude larger:

[https://github.com/isocpp/CppCoreGuidelines/blob/master/CppC...](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md)

------
rightbyte
"If thy header files fail to declare the return types of thy library
functions, thou shalt declare them thyself with the most meticulous care, lest
grievous harm befall thy program.

The prophet Ansi, in her wisdom, hath added that thou shouldst also scourge
thy Suppliers, and demand on pain of excommunication that they produce header
files that declare their library functions. For truly, only they know the
precise form of the incantation appropriate to invoking their magic in the
optimal way."

This commendment made me afraid of the dark. Was it common in those days to
have to guess to calling convention of libfunctions?

------
dang
See also from 2010:
[https://news.ycombinator.com/item?id=1876981](https://news.ycombinator.com/item?id=1876981)

------
zoomablemind
I'd supplement the first commandment with "Fear not the -Wall, for it clears
thou path to truth".

Personal reminder: "Initialize thou variables or endure the torturous trials
of doubtful debugging"

"Never refuse the helping hand of thou compiler" and "No one seeking a refuge
after arduous truth seeking journey in C has been turned away from
StackOverflow."

------
CalChris
_Thou shalt not follow the NULL pointer_ should probably be appended with _and
thou shalt not map the zero page._

~~~
beefhash
Kind of hard when the operating system does it for you...
[https://groups.google.com/d/msg/comp.unix.aix/0dv4N0qmgVQ/ty...](https://groups.google.com/d/msg/comp.unix.aix/0dv4N0qmgVQ/tyhnSiOLD0cJ)

~~~
CalChris
OSX (well, OSX ld, not OSX itself) actually does this for you and unmaps the
entire low 4GB for good measure, giving new meaning to 32-bit clean.

------
maallooc
11\. Thou shalt try C++ or Rust

~~~
oconnor663
I wonder if anyone's ever tried something like "C with slices, destructors,
and copy/move semantics".

~~~
Espressosaurus
That plus "avoid pure virtual classes", "no use of the heap", "C standard
library and header-only libraries only", "compile with no exceptions" gets you
close to embedded C++. Except also with classes.

~~~
jmiskovic
Is this something you would recommend to newcommers? I wouldn't. I can agree
that on technical level such subset has a decent set of features and gets the
job done. On the other hand when learning how to use this subset, you'll still
come across stack overflow answers and other C++ materials that will
contradict such methodology, and other coworkers will occasionally challenge
that particular stack of choices with their own favourite C++ features. You
still have to learn how exceptions work and why avoid them, what is heap and
how to disable it, what are pure virtual classes and so on.

I dislike the argument that C++ is great because you can limit yourself to
appropriate subset. It becomes a different thing while still being called C++,
which is miscommunication. If you can brand your subset as EmbeddedC++ and
gain widespread audience, then we're closer to good thing. (except there's lot
of embedded happening on Linux boards where "normal" C++ is acceptable)

My frustration mostly comes from working on huge embedded C++ project where
each separate corner of codebase used its own subset of language. This brings
down complexity and reduces mental overhead locally, but reasoning about the
whole system is impossible.

~~~
suyjuris
I would much rather recommend something like "C with bounds-checked arrays"
than a form of "standard" C++ to newcomers. Yes, StackOverflow will not help
much, but I think avoiding the huge amount of features that the rest of C++
brings is well worth it. You are probably not advocating for dumping
everything at once onto a beginner, so why not pick a subset that is both
really small and gets you quite far?

> You still have to learn how exceptions work and why avoid them, what is heap
> and how to disable it, what are pure virtual classes and so on.

Do you mean later on? As I see it, you _do not_ have to learn about the things
you do not use and can concentrate on the basics. Once you are comfortable and
need to venture out into projects where other parts of C++ are used, you would
need to, of course.

~~~
jmiskovic
Yeah I think our views are mostly aligned.

I was pointing out that if you as beginner manage to set correct boundaries
for C++, you still need to know what's on the other side in order to avoid it.
You've constrained yourself to smaller language (a good thing), but you
haven't eliminated all the baggage / mental overhead that rest of C++ brings.
The optimal approach would be to pick a language that's already well suited to
problem. I would always choose enhanced C over degraded C++.

~~~
suyjuris
Yeah, I certainly agree that the features cost you even if you do not use
them.

------
Taniwha
This probably needs some context ... C at the time was still developing, lots
of stuff was optional, parameters were int if you didn't define their type. V6
unix was a decade old and already wouldn't compile on K&R compilers, struct
became genuinely unique types (requiring the creation of union, because struct
could no longer be tweaked to do the same thing).

This was written at the end of that period where most people had an
understanding of 'how it should be', while others were still using some of the
older idiom ....

------
illuminated
Instead of the second, I'd rather put: "Thou shalt understand pointers, before
using them"

~~~
pm215
The second item is warning against a particular misuse of pointers that was
apparently widespread at the time. On VAX Unix, it happened that the memory at
address zero of a process was readable and contained zeroes. So a lot of code
would misuse a NULL pointer as being equivalent to a pointer-to-an-empty-
string, for instance: worked fine on the VAX!. So it's kind of a specific
flavour of commandment 10. These days the common machines don't have a
readable address zero, and all the old non-portable code has faded into
history.

~~~
asveikau
16-bit x86 also had the interrupt handler table at linear address 0, I seem to
recall some compilers for DOS that would make NULL point at that.

~~~
oriolid
Yes. At least writing to interrupt vector table usually crashed your computer
right at the point. I remember a certain DSP architecture that system flags
near zero address. It was an interesting experience to debug a program that
failed because a write to struct member through null pointer switched the
machine to a different instruction set.

------
matt-attack
Can someone explain #9?

~~~
rramadass
[https://stackoverflow.com/questions/38035628/c-why-did-
ansi-...](https://stackoverflow.com/questions/38035628/c-why-did-ansi-only-
specify-six-characters-for-the-minimum-number-of-significa)

~~~
HankB99
Better explanation than mine - thanks I learned something.

------
LoSboccacc
this and the tao of programming were foundational to my young mind in the
nineties, but while the commandments somewhat hold true, the commentary aged a
little.

------
_sbrk
I wish more programmers obeyed #7.

~~~
einpoklum
For C, obeying #7 is not even that difficult. It's much more of a challenge in
C++ and probably Rust (and other languages).

~~~
estebank
> 7 _Thou shalt study thy libraries and strive not to reinvent them without
> cause, that thy code may be short and readable and thy days pleasant and
> productive._

> Numberless are the unwashed heathen who scorn their libraries on various
> silly and spurious grounds, such as blind worship of the Little Tin God
> (also known as ``Efficiency''). While it is true that some features of the C
> libraries were ill-advised, by and large it is better and cheaper to use the
> works of others than to persist in re-inventing the square wheel. But thou
> should take the greatest of care to understand what thy libraries promise,
> and what they do not, lest thou rely on facilities that may vanish from
> under thy feet in future.

I'm not sure I follow. Why this would be difficult in any language with a
usable package manager and a reasonable ecosystem?

~~~
einpoklum
Most people don't even know what's available to them in the standard library
of C++ and under-use things in it. Especially STL algorithms but not just
that.

------
kstenerud
I was with them until "one true brace style". The rest are good advice.

~~~
komali2
Same but for perhaps a different reason

> As a lamentable side issue, there has been some unrest from the fanatics of
> the Pronoun Gestapo over the use of the word ``man'' in this Commandment,
> for they believe that great efforts and loud shouting devoted to the ritual
> purification of the language will somehow redound to the benefit of the
> downtrodden (whose real and grievous woes tendeth to get lost amidst all
> that thunder and fury). When preaching the gospel to the narrow of mind and
> short of temper, the word ``creature'' may be substituted as a suitable
> pseudoBiblical term free of the taint of Political Incorrectness.

Not sure that was necessary. If you happen to disagree that Language is a
valid place to fight for gender equality, you'd better serve your cause
ignoring calls to equalize your language, rather than go on an anti-PC rant
that smacks of an alt-right /r/unpopularopinion post. Just Another Old Man
Yelling At Clouds.

~~~
dragonwriter
> If you happen to disagree that Language is a valid place to fight for gender
> equality, you'd better serve your cause ignoring calls to equalize your
> language, rather than go on an anti-PC rant that smacks of an alt-right
> /r/unpopularopinion post.

What if you happen to want to signal solidarity with the alt-right crowd? Why
assume a flamboyant alt-right-style rant is an accidental coincidence? (Nto
sure of the 1990 date is for the commandments, the annotations, or both, but
in ant case, while it wasn't called the alt-right then, the subculture and
attitudes certainly existed at the time this was written; 1990 would have been
well into the first wave of it's vigorous embrace of flamboyant attacks on
“political correctness” as a signal of group identity, which started in the
mid-1980s as I recall.)

~~~
WalterBright
The PC movement began well before the 1980s.

~~~
dragonwriter
> The PC movement began well before the 1980s.

There's no such thing as “the PC movement”; every ideological movement has
ideas of correct usage of terminology related to the ideas that motivate the
movement, the term “political correctness” has been used as a derogatory term
for different of those ideas among different and unrelated ideological
movements at different times. (e.g., in the 1930s-1950s it was used in a New
York times article describing Nazi drive for uniformity in expressed ideas, as
well as by American Socialists attacking the American Communists.)

However, attacks against expression of anti-sexist and anti-racist ideas as
“political correctness” by the same segment of the American Right has been
extremely popular twice, the first in the 1980s-1990s, and the second we're in
right now.

------
pwdisswordfish2
> Beware, in particular, of the subtle and terrible ``All the world's a 32-bit
> machine'', which is almost true today but shall cease to be so before thy
> resume grows too much longer.

That’s cute. What year was it written?

~~~
mellosouls
1987 by the look of it.

[https://groups.google.com/forum/#!msg/comp.lang.c/CYgWkWdWCc...](https://groups.google.com/forum/#!msg/comp.lang.c/CYgWkWdWCcQ/thMt3RfByAgJ)

~~~
qubex
Yeah... the reference to the abundance of VAXen isn’t something one encounters
often this side of the fall of the Berlin Wall.

~~~
pwdisswordfish2
Which side is that?

~~~
Y_Y
The outside

~~~
pwdisswordfish2
What about HN readers/commenters on the inside?

------
lihaciudaniel
>Thou shalt study thy libraries and strive not to reinvent them without cause,
that thy code may be short and readable and thy days pleasant and productive.

That's why my teacher ought to go to hell, how many times do I need to say
that

~~~
monocasa
There's a difference between re-implementing to understand, and re-
implementing to ship into production.

It's common for a blacksmith to make a set of tools as a exercise, but they'll
also commonly get some quality tools to do real work with.

