views:

364

answers:

13

Let's say that I have a binary that I am building, and I include a bunch of files that are never actually used, and do the subsequent linking to the libraries described by those include files? (again, these libraries are never used)

What are the negative consequences of this, beyond increased compile time?

+6  A: 

A few I can think of are namespace pollution and binary size

Does it really increase binary size? For a dynamically linked library I wouldn't think that it would.
windfinder
it wouldn't indeed, the namespace pollution is hell though
MahdeTo
How about with static linking?
windfinder
Do smarter linkers just skip linking unreferenced libs? I recall something with "opt ref" messages from VC++??
Aardvark
@windfinder: For dynamic libraries it is a two-fold hell: 1)version control for an excessive number of header files (good luck maintaining accross versions),2) still affects side, albeit marginally, at it has to maintain references to functions...
If functions are not called, there are no references to functions and hence no increase in size, whether the library is dynamic or static. As for namespace polution, this is exactly what C++ namespaces were introduced to control, so no problem there either.
anon
+1 Neil. That's why you link with a "library", rather than just raw object files.
j_random_hacker
One you left out: it makes your program depend on having those libraries present at runtime, forcing users to install unnecessary libraries.
R..
+4  A: 

In addition to what Sasha lists is maintenance cost. Will you be able to detect easily what is used and what is not used in the future when and if you chose to remove unused stuff?

Doug T.
+5  A: 

In addition to compile time; Increased complexity, needless distraction while debugging, a maintenance overhead.

Apart from that, nothing.

Ed Guiness
+4  A: 

If the libraries are never used, there should be no increase in size for the executable.

anon
+1, there's no reason for the linker to add object files that aren't referenced anywhere.
Bastien Léonard
But only if the linker can guarantee that the objects are not referenced from another compilation unit/library. Now the linker does strips out objects from statically linked libraries that are not explicitly used (hence link order is significant) but NOT from the main executable body.
Martin York
Link order for UNIX linkers typically IS significant and you may have to link the same lib several times precisely because they are (too!) good at removing unreferenced symbols
anon
+1. Dependency checking is what distinguishes a "library" from being just a huge object file.
j_random_hacker
+3  A: 

Depending on the exact linker, you might also notice that the global objects of your unused libraries still get constructed. This implies a memory overhead and increases startup costs.

MSalters
+1, interesting. Does the C++ standard have a stance on this?
j_random_hacker
Yup, "initialize before first call of a function in the .cpp defining the global". "When the library loads" is such a moment, and easy to detect.
MSalters
Ah thanks. Yes according to that, it's legal to either (a) not construct it at all, since no functions in that source file will be called; or (b) construct it at any time. Yuck :(
j_random_hacker
A: 

I have never experienced any problems with linking a .lib file of which only a very small part is used. Only the code that is really used will be linked into the executable, and the linking time did not increase noticeably (with Visual Studio).

Dimitri C.
A: 

If you link to binaries and they get loaded at runtime, they may perform non-trivial initialization which can do anything from allocate a small amount of memory to consume scarce resources to alter the state of your module in ways you don't expect, and beyond.

You're better off getting rid of stuff you don't need, simply to eliminate a bunch of unknowns.

John Dibling
+1  A: 

If the libraries you're including but not using aren't on the target system, it won't be able to compile even though they aren't necessary.

tstenner
+1  A: 

Here is my answer for a similar question concerning C and static libraries. Perhaps it is useful to you in the context of C++ as well.

sigjuice
+1  A: 

You mention an increase in the compilation time. From that I understand the libraries are statically linked, and not dynamically. In this case, it depends how the linker handles unused functions. If it ignores them, you will have mostly maintenance problems. If they’ll be included, the executable size will increase. Now, this is more significant than the place it takes on the hard drive. Large executables could run slower due to caching issues. If active code and non-active code are adjacent in the exe, they will be cached together, making the cache effectively smaller and less efficient.

VC2005 and above have an optimization called PGO, which orders the code within the executable in a way that ensures effective caching of code that is often used. I don’t know if g++ has a similar optimization, but it’s worth looking into that.

eran
+1  A: 

A little compilation here of the issues, wiki-edit it as necessary:

The main problem appears to be: Namespace Pollution This can cause problems in future debugging, version control, and increased future maintenance cost.

There will also be, at the minimum, minor Binary Bloat, as the function/class/namespace references will be maintained (In the symbol table?). Dynamic libraries should not greatly increase binary size(but they become a dependency for the binary to run?). Judging from the GNU C compiler, statically linked libraries should not be included in final binary if they are never referenced in the source. (Assumption based on the C compiler, may need to clarify/correct)

Also, depending on the nature of your libraries, global and static objects/variables may be instantiated, causing increased startup time and memory overhead.

Oh, and increased compile/linking time.

windfinder
+1  A: 

I find it frustrating when I edit a file in the source tree because some symbol that I'm working on appears in the source file (e.g. a function name, where I've just changed the prototype - or, sadly but more typically, just added the prototype to a header) so I need to check that the use is correct, or the compiler now tells me the use in that file is incorrect. So, I edit the file. Then I see a problem - what is this file doing? And it turns out that although the code is 'used' in the product, it really isn't actively used at all.

I found an occurrence of this problem on Monday. A file with 10,000+ lines of code invoked a function 'extern void add_remainder(void);' with an argument of 0. So, I went to fix it. Then I looked at the rest of the code...it turned out it was a development stub from about 15 years ago that had never been removed. Cleanly excising the code turned out to involve minor edits to more than half-a-dozen files - and I've not yet worked out whether it is safe to remove the enumeration constant from the middle of an enumeration in case. Temporarily, that is marked 'Unused/Obsolete - can it be removed safely?'.

That chunk of code has had zero cove coverage for the last 15 years - production, test, ... True, it's only a tiny part of a vast system - percentage-wise, it's less than a 1% blip on the chart. Still, it is extra wasted code.

Puzzling. Annoying. Depressingly common (I've logged, and fixed, at least half a dozen similar bugs this year so far).

And a waste of my time - and other developers' time. The file had been edited periodically over the years by other people doing what I was doing - a thorough job.

Jonathan Leffler
+1. In summary: "More code => more maintenance." And in my experience, maintenance time grows more than linearly with codebase size.
j_random_hacker
I'd agree with that analysis. That makes the software I work on, and things like MS Windows, extremely hard to maintain!
Jonathan Leffler
A: 

It could perhaps even fail to compile if the build tree isn't well maintained. if your'e compiling on embedded systems without swap space. The compiler can run out of memory while trying to compile a massive object file.

It happened at work to us recently.

sheepsimulator