Home > Articles > Programming > C/C++

  • Print
  • + Share This
From the author of The Standard Library

The Standard Library

Although not specific to C, one of the biggest headaches for portability between operating systems is the use of nonstandard library functions. This is particularly common for GNU/Linux developers, who have a habit of assuming that glibc is the only possible libc that anyone will use.

If you're writing *NIX code, it's worth keeping a copy of the Single UNIX Specification on hand. (You can find the latest version in the Open Group's website.) Check this before you use C library functions, and make sure that they're in the standard. If they are, but aren't widely supported, this doesn't help much, but it means at least that portability problems are not your fault (and that they're likely to diminish in the future, as libc authors aim to implement the standards). On some systems, the man pages are good at telling you which things are nonportable. On GNU systems, this frequently isn't the case.

If you want to use some libc functions that aren't standard, but are from a permissively licensed implementation, you have another option—the approach taken by OpenSSH. It uses some features that originally come from OpenBSD libc, such as strlcat(), and provides copies of the implementations of these functions for libc versions that don't provide them (which, these days, means glibc).

Differences between compilers and standard library implementations can also affect the identifiers that you can use. Most C compilers allow you to use identifiers that start with underscores (_). In fact, some coding conventions suggest that you prefix private symbols with an underscore. This is a problem, because the C standard explicitly reserves these symbols for the implementation.

Unfortunately, the implementation includes both the standard library and the compiler, and no part of the current standard defines which identifiers are reserved for the compiler and which are reserved for the libc. GNU C reserves all identifiers that start with a double underscore, or an underscore and then an uppercase letter, for the compiler. A single underscore followed by anything else is for the use of the libc.

Unfortunately, GNU libc is maintained by someone who is incapable of reading either the C standard or the GNU C documentation and therefore uses identifiers with double underscores in various places. This means that you may encounter problems using glibc headers with any compiler that isn't the default at Red Hat. As a concrete example, the glibc unistd.h contains some identifiers called __block, which is a reserved type qualifier with Apple GCC and with clang, meaning that you can't include this file and use blocks in the same compilation unit without some explicit hackery to work around this problem.

Make sure that you don't make the same mistake in your own code. Don't start identifiers with underscores unless you're writing a libc implementation and have checked your compiler's documentation to make certain that it allows you to use them. Under no circumstances should you use them for parameter names or local variables—you introduce potential problems and gain nothing in collision-avoidance.

  • + Share This
  • 🔖 Save To Your Account