Why is C++ initial allocation so much larger than C's?

Rerumu picture Rerumu · Jun 20, 2019 · Viewed 8.2k times · Source

When using the same code, simply changing the compiler (from a C compiler to a C++ compiler) will change how much memory is allocated. I'm not quite sure why this is and would like to understand it more. So far the best response I've gotten is "probably the I/O streams", which isn't very descriptive and makes me wonder about the "you don't pay for what you don't use" aspect of C++.

I'm using the Clang and GCC compilers, versions 7.0.1-8 and 8.3.0-6 respectively. My system is running on Debian 10 (Buster), latest. The benchmarks are done via Valgrind Massif.

#include <stdio.h>

int main() {
    printf("Hello, world!\n");
    return 0;
}

The code used does not change, but whether I compile as C or as C++, it changes the results of the Valgrind benchmark. The values remain consistent across compilers, however. The runtime allocations (peak) for the program go as follows:

  • GCC (C): 1,032 bytes (1 KB)
  • G++ (C++): 73,744 bytes, (~74 KB)
  • Clang (C): 1,032 bytes (1 KB)
  • Clang++ (C++): 73,744 bytes (~74 KB)

For compiling, I use the following commands:

clang -O3 -o c-clang ./main.c
gcc -O3 -o c-gcc ./main.c
clang++ -O3 -o cpp-clang ./main.cpp
g++ -O3 -o cpp-gcc ./main.cpp

For Valgrind, I run valgrind --tool=massif --massif-out-file=m_compiler_lang ./compiler-lang on each compiler and language, then ms_print for displaying the peaks.

Am I doing something wrong here?

Answer

Nikos C. picture Nikos C. · Jun 20, 2019

The heap usage comes from the C++ standard library. It allocates memory for internal library use on startup. If you don't link against it, there should be zero difference between the C and C++ version. With GCC and Clang, you can compile the file with:

g++ -Wl,--as-needed main.cpp

This will instruct the linker to not link against unused libraries. In your example code, the C++ library is not used, so it should not link against the C++ standard library.

You can also test this with the C file. If you compile with:

gcc main.c -lstdc++

The heap usage will reappear, even though you've built a C program.

The heap use is obviously dependant to the specific C++ library implementation you're using. In your case, that's the GNU C++ library, libstdc++. Other implementations might not allocate the same amount of memory, or they might not allocate any memory at all (at least not on startup.) The LLVM C++ library (libc++) for example does not do heap allocation on startup, at least on my Linux machine:

clang++ -stdlib=libc++ main.cpp

The heap use is the same as not linking at all against it.

(If compilation fails, then libc++ is probably not installed. The package name usually contains "libc++" or "libcxx".)