10.1. C Language Reintroduction¶

“Program testing can be used to show the presence of bugs, but never to show their absence!”

Edsger Dijkstra

This book assumes some prior experience with the C programming language. However, the way that C is taught as a programming language and how it is used in the systems world are not always the same. As a simple example, consider the following trivial example of C code:

int maximum_size = 65536;


In many examples of systems code, this type declaration is too vague to be safe. Specifically, according to the C language specification, there is no fixed size for the int type. While an int can often be assumed (on modern laptops, desktops, or server machines) to be four bytes in size, it doesn’t have to be. On some embedded systems, for instance, an int is only two bytes in size. This declaration would then be a problem, because the value 65,536 cannot be represented as a two-byte signed integer (which range from -32,768 to 32,767). Consequently, systems programmers typically use more explicit types that clearly indicate the exact size, such as uint32_t (unsigned 32-bit integer).

This Appendix is intended as a re-introduction to the C language as used by this text. It is not intended as a complete introduction for readers who have never used C before. For instance, there is no coverage here of standard control structures, such as loops or conditional statements. We also do not cover file-related functions (such as fopen()) that use pointers to FILE instances, as these functions are oriented toward ASCII-formatted text files; systems programming typically involves working with binary-formatted data instead. Instead, this Appendix focuses on intermediate or advanced features of C that are commonly used in systems programming. We start this Appendix with a discussion of how to consult documentation and debugging, as these are critical skills for systems programming.