loading...

OpenBSD Is C Documentation

apotheon profile image Chad Perrin Updated on ・3 min read

StackOverflow is the de facto standard place to go when you need to figure out how to do something as a programmer. A web search for information about how to check the number of lines in a file using the C programming language will probably give you StackOverflow questions as the most relevant search results. Unfortunately, while writing good, clean, reliable C does not need to be difficult, it is certainly difficult to find information about how to do it well, and the people answering these questions on StackOverflow are not filtered by their skills or knowledge of good practices. From time to time, the top-rated answer or the accepted answer is even the worst answer that addresses the question.

The best example I have seen of a straightforward line count algorithm is in a place that might seem obvious after the fact: the source code of the wc command line utility. Figure out how the -l option is handled in a good implementation of wc, and all that's left is to adapt it to your needs. Ideally, the solution you find should be short, simple, careful (e.g. checking for error conditions), robust, well-worn, and well-formatted.

The C coding standards of the OpenBSD community are among the highest and most pragmatic you'll ever find, and when someone makes a decision about implementation whose reasoning is not pretty obvious in the code itself you're almost certain to see that reasoning clearly documented in code comments, which can also teach you something about being a good programmer in general. The OpenBSD source tree is the best place to start for such questions, in my experience, and it's where I went to check my own thinking about how to count lines recently.

OpenBSD is a great place to start when all you need is some guidance on what function to use for something, as well. You may have heard atoi() is not a function you should use. If you haven't heard before, you have now. There are some great resources on the internet that describe why it's a terrible idea to use atoi(), and a plethora of other deprecated functions in good C programming. What should you use instead?

That's a good question, and it turns out OpenBSD has the answer, in almost every case, in a manpage. Use the man atoi command on an OpenBSD system, and you'll find a caveats section of the file that talks about strtol(), strtoul(), and strtonum() as alternatives; check their manpages for more details. (Spoiler: strtonum() is almost always what you want.) The same applies to things like why you should generally use snprintf() instead of sprintf() (explained in the caveats section for both functions and a bunch of related functions), strlcat() instead of strcat() (in the description section of man strcat), and strncmp() instead of strcmp() (they share a manpage, which includes information about why to choose one over the other). If you don't have easy access to an OpenBSD system, you can always check OpenBSD manpages online, too.

The "check OpenBSD" technique is not perfect for finding the best ways to do things in all cases, but it's the quickest, easiest way to get a better idiom or function choice than you would likely have found otherwise. In the majority of cases when something is in the OpenBSD codebase or OpenBSD's manpages it's about the best you're likely to get. An example of a slight shortcoming is that, while the manpage for malloc() and calloc() does give good guidance for reasons to prefer calloc() most of the time in the caveats section, it is not explicit about one of the most important reasons: zeroing out the memory you just allocated, automatically, to protect leftover data from software previously running on the system (for instance). That manpage also talks about initialization overhead for calloc(), but it turns out calloc() is often faster than malloc() for reasons of arcane implementation details.

That, however, is not something you will likely find in a web search for the best way to allocate memory in C at all, possibly excepting specific searches for all the gory details about how malloc() and calloc() work under the hood. The fact that StackOverflow answers will give malloc() solutions where calloc() would be better, as often as not, helps make my point. There's a lot of information on StackOverflow, but let the reader beware. Sanity-check the answers against OpenBSD source code and documentation.

In short, when you need to write C, OpenBSD is excellent C documentation.

Posted on by:

apotheon profile

Chad Perrin

@apotheon

I'm a developer who likes testing first, iterative processes, and refactoring, and I care about quality. I speak both C and Ruby with some facility, and enjoy both, which confuses some people.

Discussion

pic
Editor guide
 

If you ask me, OpenBSD is a bunch of hypocritical morons sitting too high on their horses to be taken seriously.

Out of curiosity I had a look at the C code and one of the latest merged pull request introduces code like this:

if ((*dst++ = *src) == '\0') break;

That is stereotypical of bad dangerous unreadable code.

Honestly I would look for other sources of inspiration if I were you :)

 

How many OpenBSD developers have you actually interacted with?

I think you might be perpetuating a stereotype.

Can you share a link to the pull request?