What are the C and C++ Standard Libraries?

A brief tour into the realm of writing C/C++ applications, the role of the Standard Library and how it is implemented in various operating systems.

I have been playing around with C++ for a while and one thing that always got me confused in the beginning was its anatomy: where do the core functions and classes I'm using come from? Who invented them? Are they packaged somewhere in my system? Is there a kind of official C++ manual around?

In this article I will try to answer these questions, by taking a tour from the very essence of C and C++ languages to their actual implementations.

How C and C++ are made

When we talk about C and C++ we are actually referring to a set of rules defining what the languages should do, how they should behave and what functionalities they should provide. A C/C++ compiler must follow these rules in order to process source code written in C/C++ and generate binary applications. This sounds very close to HTML: a set of directives that browsers follow so that they can render web pages in a definitive way.

As with HTML, the C and C++ rules are theoretical. A large group of people at the International Organization for Standardization (ISO) gather themselves several times a year to discuss and define on paper the languages rules. Yes, C and C++ are standardized things. They eventually end up with an official book called standard you can purchase from their website. New papers get released as the languages evolve, each time defining a new standard. That's why we have different C and C++ versions: C99, C11, C++03, C++11, C++14 and so on, where the number matches the publication year.

The standards are very detailed and technical documents: I wouldn't use them as handbooks. They are usually split into two parts:

the C/C++ features and functionalities; the C/C++ API — a collection of classes, functions and macros that developers use in their C/C++ programs. It is called the Standard Library.

For example, here is a selection from the first part of a C standard where the anatomy of the main function is defined:

This is another excerpt from the same standard describing a member of the C API — the fmin function:

As you can see, almost no code is involved. Someone has to read the standard and transform it into something a computer can digest. This is what people working on compilers and implementations do: the former crafts a tool that can read and process C and C++ source files, the latter turns the Standard Library into code. Let's take a deeper look at it.

C Standard library

The C Standard Library, also known as ISO C Library is a collection of macros, types and functions for tasks such as input/output processing, string handling, memory management, mathematical computations and many other operating system services. It is specified in the C standard (e.g. the C11 standard). The content is spread across different headers, like math.h I've mentioned above.

C++ Standard library

The same C Standard Library concept, but specific for C++. The C++ Standard Library is a set of C++ template classes which provides common programming data structures and functions such as lists, stacks, arrays, algorithms, iterators and any other C++ component you can think of. The C++ Standard Library incorporates the C Standard Library too and it is specified in the C++ standard (e.g. the C++11 standard).

Implementing the C and C++ Standard Library

We start talking about real code here. Developers who work on the Standard Library implementation read the official ISO requirements and translate them into code. They have to rely upon the functionalities provided by their operating system (read/write files, allocate memory, create threads, ..., through the so-called system calls), so each platform has its own Standard Library implementation. Sometimes it's a core part of the system, sometimes it comes as an additional component — the compiler — that must be downloaded separately.

GNU/Linux implementation

The GNU C Library, also known as glibc, is the GNU Project's implementation of the C Standard Library. Not all standard C functions are found in glibc: most mathematical functions are actually implemented in libm, a separate library.

As of today glibc is the most widely used C library on Linux. However, during the ‘90s there was for a while a glibc competitor called Linux libc (or just libc), born from a fork of glibc 1.x. For a while, Linux libc was the standard C library in many Linux distributions.

After years of development, glibc turned out to be way superior to Linux libc and all Linux distributions that had been using it switched back to glibc. So don't worry if you find a file in your disk named libc.so.6 : it's the modern glibc. The version number got incremented to 6 in order to avoid any confusion with the previous Linux libc versions (they couldn't name it glibc.so.6 : all Linux libraries must start with the lib prefix).

On the other hand, the implementation of the C++ Standard Library takes place in libstdc++ or The GNU Standard C++ Library. It is an ongoing project to implement the Standard C++ library on GNU/Linux. In general all commonly available linux distributions will use libstdc++ by default.

Mac and iOS implementation

On Mac and iOS the C Standard Library implementation is part of libSystem, a core library located in /usr/lib/libSystem.dylib . LibSystem includes other components such as the math library, the thread library and other low-level utilities.

Regarding the C++ Standard Library, on Mac before OS X Mavericks (version 10.9) libstdc++ was the default. That's the same implementation that can be found in modern Linux-based systems. Starting from OS X Mavericks, Apple switched to libc++, a replacement for the GNU libstdc++ Standard Library introduced by the LLVM project, the official Mac compiler framework.

IOS developers can enter the Standard Libraries using the iOS SDK (Software Development Kit), a set of tools that allows for the creation of mobile apps.

Windows implementation

On Windows the implementation of the Standard Libraries has always been strictly bound to Visual Studio, the official Microsoft compiler. They use to call it C/C++ Run-time Library (CRT) and it covers both implementations.

In the very beginning, the CRT was implemented as the CRTDLL.DLL library (no C++ Standard Library back then, I suppose). From Windows 95 on, Microsoft started shipping it as MSVCRT[version-number].DLL (MSVCR20.DLL, MSVCR70.DLL, and so on), presumably with C++ Standard Library as well. Around 1997, they decided to simplify the file name into MSVCRT.DLL, which unfortunately led to a nasty DLL mess. That's why, starting from Visual Studio version 7.0, they switched back to ship DLLs for each version.

Visual Studio 2015 brought a deep CRT refactoring. The C/C++ Standard Library implementation moved into a new library, the Universal C Runtime Library (Universal CRT or UCRT) compiled as UCRTBASE.DLL. The UCRT has now become a Windows component, shipped as part of the operating system starting from Windows 10.

Android implementation

Bionic is the C Standard Library implementation written by Google for its Android operating system, which uses it directly under the hood. Third-party developers have access to Bionic through the Android Native Development Kit (NDK), a tools set allowing you to use C and C++ code for writing Android apps.

On the C++ side, the NDK offers several implementations:

libc++ , the official C++ Standard Library for Android, used since Lollipop and in modern Mac operating systems. Starting from NDK release 17 it will become the only C++ Standard Library implementation available in the NDK;

gnustl , an alias for libstdc++, the very same library available in GNU/Linux. The use of this library is deprecated and it will be removed in NDK release 18;

STLport, a third-party implementation of the C++ Standard Library written by the STLport project, inactive since 2008. Like gnustl, STLport will be removed in NDK release 18.

Can I replace the default implementation with a different one?

You usually want to include a different implementation of the C Standard Library if you are working on systems characterized by extremely limited resources. uClibc-ng, musl libc and diet libc to name a few, all of them geared towards developing in embedded Linux systems, providing smaller binaries and smaller memory footprints.

There are different implementations of the C++ Standard Library as well: the Apache C++ Standard Library, uSTL or EASTL to name a few. The last two actually take care only of the template part, not of the full library and they are developed with speed in mind. The Apache version is focused on portability instead.

What if I get rid of the Standard Library?

Not using the Standard Library is very easy: just don't import any of its header in your program and you are done. However, in order to make this operation meaningful you need to interact somehow with the operating system, through the provided system calls. As I said before this is what the functions/methods in the Standard Library use under the hood for their implementation. Quite possibly you would also have to call assembly routines to interface to hardware devices.

If this sounds exciting to you, some people over the Internet are trying to create working programs without involving Standard Library. This way you lose portability, because you rely upon functions provided by a specific operating system. However going the hard way may teach you a lot and make you more aware of what you are doing even when using high level libraries.

Besides erudition, you don't want to include the Standard Library when working on embedded systems: with limited memory available every byte matters so you tend to write more assembly because the code doesn't need to be portable. The demoscene is another setting where people strive to fit beautiful audio-visual presentations into program binaries of limited size — 4K still isn't the lowest border: some demoparties organize 1K, 256 byte, 64 byte or even 32 byte intro competitions. No Standard Library allowed in there!

Sources

Mac OS X for Unix Geeks - 5.2. The System Library: libSystem (link)

libcxx.llvm.org - "libc++" C++ Standard Library (link)

blogs.msdn.microsoft.com - Windows is not a Microsoft Visual C/C++ Run-Time delivery channel (link)

malsmith.net - A visual history of Visual C++ (link)

docs.microsoft.com - CRT Library Features (link)

MicrosoftDocs @ GitHub - Upgrade your code to the Universal CRT (link)

Stackoverflow - What the role of libc(glibc) in our linux app? (link)

Stackoverflow - Where is the standard C library on Mac OS X? (link)

Stackoverflow - When is it necessary to use use the flag -stdlib=libstdc++? (link)

Stackoverflow - Where is the C/C++ Standard Library in Android and iOS? (link)

Stackoverflow - iOS help: math.h? Where is this? (link)

Stackoverflow - What can you do in C without “std” includes? Are they part of “C,” or just libraries? (link)

developer.android.com - C++ Library Support (link)

Wikipedia - Bionic (link))

Wikipedia - C standard library (link)

Wikipedia - GNU C Library (link)

Wikipedia - Microsoft Windows library files (link)

Wikipedia - Demoscene (link)

android.googlesource.com - NDK Roadmap (link)

Reddit - What is the relationship between gcc, libstdc++, glibc, binutils? (link)

man7.org - LIBC(7) (link)

gnu.org - The GNU C Library (glibc) (link)