Created attachment 7595 [details] Tarball of the testcase. This is an enhancement request. In ld 2.23.1, gc-sections fails to remove some unused C++ class members. This is causing binaries linked with static C++ libs to be megs larger than they could be. Each function is correctly in a separate section, and is not referenced anywhere in the app. Attaching a reduced testcase, and also posting the code as comments.
lib.h: #ifndef FOO_H #define FOO_H class interface { public: virtual void foo() = 0; virtual void bar() = 0; }; interface* getclass(); #endif
lib.cpp: #include <stdio.h> #include "lib.h" class myclass: public interface { public: void foo() { puts("foo"); } void bar() { puts("bar"); } }; interface *getclass() { return new myclass; }
app.cpp: #include "lib.h" int main() { interface *i = getclass(); i->bar(); return 0; }
Hi Curaga, What extraneous code is left in the executable ? Does the problem persist with the 2.24 relase or the current mainline development sources ? Cheers Nick
It fails to remove the function foo, which is in its own section _ZN7myclass3fooEv and unused. It still happens on current git, 2.24.51.20140618 or 6a83deeaa804 (Brown paper bag ...).
Have you tried enabling link-time optimization in gcc. Ie compiling with -lfto added to the g++ command lines. This appears to work for the test case you supplied. The problem I believe is related to the virtual nature of the functions, which are not invoked directly, but rather via pointers stored in a table. The linker is not sophisticated enough to be able to determine which entries in a given table are unused, so it cannot delete the unneeded virtual functions. Cheers Nick
That's why this is an enhancement request :) I'd like to see that sophistication added to the linker. This is needed separately from LTO for various reasons: - use with older compilers that do not support LTO - use with projects so big that LTO cannot be used (Firefox, Webkit) because of prohibiting RAM requirements - use with projects that need fast compilation, but small binaries. LTO comes with a severe compile time hit - use with projects that are buggy with LTO It's completely feasible without LTO and would benefit many cases. LTO is problematic in some cases, slow, and RAM-hungry, whereas gc-sections has not failed me once, and is quite fast and light on RAM in comparison.
What you'd need is some way for the linker to recognise that references from vtables should not be followed for the purpose of marking sections against garbage collection, and some way of marking the functions called at their call sites. The former is easy enough, the latter is impossible. The linker can't know the function called, by the very nature of virtual functions.