1

Assuming I'm working in an IDE like Visual Studio to program in C or C++. Let's say I decide to statically link to an object file. Because I'm using Visual Studio, I configure the project properties linker settings (i.e. I don't edit a make file). What happens if I don't actually use any of the linked code in my program? What will the compiled code look like? Will it be bloated?

Will the IDE check for such cases to optimize the makefile? Or could the compiler check for this? Would it depend on the compiler?

Essentially this question was motivated by me not knowing what libraries I will need to use from SFML, thus I decided to link to all the libraries as a temporary action. Would linking to object files that aren't implemented bloat my binaries? Or would they be optimized away by the IDE, compiler, etc.?

isanae
  • 3,107
  • 1
  • 21
  • 42
Izzo
  • 3,882
  • 12
  • 35
  • 66
  • 3
    You'll get linker errors? – πάντα ῥεῖ Aug 21 '16 at 17:59
  • 8
    Why don't you simply try it? Btw, the linker will only include the parts of a static library that you actually *use* in the final executable. – Jesper Juhl Aug 21 '16 at 18:01
  • https://en.wikipedia.org/wiki/Linker_(computing) – user3386109 Aug 21 '16 at 18:06
  • @JesperJuhl There appeared to be no noticeable size difference in the outputted binaries. I wasn't sure if I could generalize just based on this one instance. However, your comment about only including parts of a static library that are actually used answers my question. – Izzo Aug 21 '16 at 18:07
  • What Jesper mentions is actually a linker setting. Not all linkers will do it (though most modern ones will), and it likely requires enabling optimizations. – Cody Gray Aug 21 '16 at 18:09
  • 1
    This is the linker switch. https://msdn.microsoft.com/en-us/library/bxwfs976.aspx It defautls to /OPT:REF in a Release build of Visual Studio. – selbie Aug 21 '16 at 18:12
  • I think you misused the word "implemented" and meant the opposite, "used". – R.. GitHub STOP HELPING ICE Aug 21 '16 at 21:55

1 Answers1

2

Most optimizers are able to find and eliminate dead code, and that includes functions that are never called. On Visual C++, this requires at least the /Gy flag ("Enable Function-Level Linking") to the compiler. Other flags should be on by default.

> type a.cpp
#include <iostream>

void not_called()
{
    std::cout << "Hello, world!\n";
}

int main()
{
}

> cl /nologo /EHsc /Gy a.cpp /link /verbose | findstr not_called
    Discarded "void __cdecl not_called(void)" (?not_called@@YAXXZ) from a.obj

The /Gy flag packages individual functions into COMDATs, which gives more information to the linker and allows it to remove unused or redundant functions. The linker flag /OPT:REF ("eliminates functions and data that are never referenced") is also required, but it's on by default.

Visual C++ will set these flags correctly by default in Release mode when you create a new project. However, if you're statically linking with a library, you have to make sure it was also compiled with /Gy.

Note that none of this applies to linking with a DLL. Since it's impossible to tell in advance what functions will be used when building it, the DLL will always contain everything that was exported.

Community
  • 1
  • 1
isanae
  • 3,107
  • 1
  • 21
  • 42