Question

first I'll create a small program:

#include <gmpxx.h>

void function() {
    //mpf_class num;
    return;
}

int main() {}

Notice, that I am including a 3rd party library, but not using any of its contents.
I go to compile the program:

$ g++ main.cpp -Wl,--as-needed -lgmp -lgmpxx
$ readelf -d a.out | grep NEEDED
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]

Even though I linked two additional libraries to this program, I passed the flag --as-nedded which discovered that those two libraries were not actually needed at run-time. Therefore, readelf shows us that they were not actually linked.

(gcc actually links additional c and c++ libraries to your binary besides libc, but the --as-needed flag discovered that those too, were not needed.)

Here I reference the library code, but still don't actually need it:

#include <gmpxx.h>

void function() {
    mpf_class num;
    return;
}

int main() {}

$ g++ main.cpp -Wl,--as-needed -lgmp -lgmpxx
$ readelf -d a.out | grep NEEDED
 0x0000000000000001 (NEEDED)             Shared library: [libgmp.so.10]
 0x0000000000000001 (NEEDED)             Shared library: [libstdc++.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libgcc_s.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]

Question: I was under the assumption that unused functions get thrown away, and don't become part of the binary. Assuming the compiler realizes that the "function" code is not needed, and can toss it, why can't it also realize that the linking of gmp is also no longer needed?

Interestingly, running the command with full optimization,

$ g++ -Ofast main.cpp -Wl,--as-needed -lgmp -lgmpxx
$ readelf -d a.out | grep NEEDED
 0x0000000000000001 (NEEDED)             Shared library: [libgmp.so.10]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]

results in some of gcc's implicitly linked libraries to be excluded when previously unoptimized were kept due to gmp's inclusion.

Question: Is the compiler capable of excluding that 3rd party library given that the library code will never actually be executed?

Was it helpful?

Solution

If the compiler is absolutely sure some code won't ever be used, it is allowed to just throw it away. If so, the call won't show up in the object, and the library ommited.

In the example function that isn't called, it is by default extern, so the compiler can't know if it is called from another file, and isn't allowed to get rid of it. But most compilers just compile a function at a time, and do little intra-function analysis. So I doubt any current compiler will compile that file (with a static void function()), notice the function isn't called, and delete it. Perhaps a smart linker (which does whole-program analysis) will do so, but I haven't looked too closely at that.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top