Making C Programs Small: The Beauty of C
Introduction
Let’s write a simple hello-world program in C language and compile a static binary with GCC:
|
|
First, let’s just compile it and check the size of the stripped binary file:
|
|
It’s 15K, but this is not a static binary and uses system shared libraries:
|
|
Let’s compile a static binary and check its size:
|
|
Six hundred eighty-one kilobytes for such a simple program! What a waste of space in 2020, huh? 🙈 Nevertheless, in this post, we’ll try to make our programs smaller (maybe a lot).
Getting rid of C standard library
The fact is that by default, C compilers automatically link our code with GNU C Library and most of the binary size is taken by it, so our initial goal is going to be making our program independent from that. To make it possible, we need to write an entry point to our program and wrappers for system calls in Assembler. Let’s do that (I’m using x86-64 instructions set):
Dumb calculator
For the purpose of showing that one can do something meaningful without exploiting C library, I shall implement a CLI program that takes +|-|*|/ as an operation from an argument and reduces the list from the stdin with it.
Write a Makefile:
Now let’s build and test it:
|
|
|
|
How small is it?
|
|
The size equals 9KB, which is approximately $98.7\%$ smaller than the initial hello-world program. Sounds fascinating 🎉. Of course, we become seriously limited by the inability to use functions from the standard library. However, the critical point is that we could get independent from runtime libraries and thus have almost zero initialization runtime, making C the only good choice for implementing system kernels and developing for cheap microcontrollers.
Source code of the example is available here.
P.S.
To just produce a smaller binary for simple programs such as hello-world example, we can use musl libc, which is a less-monolithic implementation of the C standard library compared to glibc.
|
|
And… we’ve got a binary that weights less than the initial dynamically-linked version.