8

Sometimes when programming, we define or declare functions, definitions, variables, macros includes and data structures. but never use those after that.

  1. Do those unused resources automatically get remove by the compiler (modern compilers capable of optimizing)?
  2. Is there a way to recognize those?
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Nayana Adassuriya
  • 23,596
  • 30
  • 104
  • 147

2 Answers2

12

It depends:

Macros are converted to program text by the compiler. They don't represent anything other than the text that replaces them, and don't live beyond compile time (unless... see below).

Local variables and such are likely removed, if they don't have a non-trivial constructor or destructor. (You don't want something like scoped_lock removed just because you don't reference it later in the code.) The same holds for variables and functions with internal linkage (e.g. defined at namespace scope with the keyword static). In most cases, however, the resources needed for such objects is minimal, and the savings negligible.

Functions are a bit different, and depend. A virtual function will generally be considered "used" if there is ever an instance of its type, and it will almost certainly be present, even if it is never called.

Beyond that (and this applies to global variables as well): it's up to the linker. The granularity of most linkers is the object file which results from compiling a "translation unit": that object file either is or is not part of your program. If you tell the linker to incorporate the object file, then you should get everything that is in it. If you put the object file in a (static) library, and tell the linker to use this, then the linker will incorporate the object file into your program if and only if it resolves an otherwise unresolved external. But if it incorporates the object file, it generally will incorporate all of it. (Any good library will put each non-virtual function in a separate object file, so you don't get more than you need.)

In this regard, DLL's behave like object files (despite their name). If you link your object files into a DLL, the program which uses it will get all of the DLL, or none.

Finally: although not part of your program, the object files and the final executable will often contain symbolic information; the best systems will even maintain information concerning macros, so that the debugger can display things the way you wrote them. (How far it can do this with macros is debatable.)

James Kanze
  • 150,581
  • 18
  • 184
  • 329
4

If either the compiler or the linker can see that there are no references to C functions or C variables, they can (and usually do) remove those unused things.

Unused macro definitions don't make it into the compiled code at all. And the same holds for typedefs and the like.

It is, however, harder to remove unused code and data implemented in the assembly parts of programs.

And it's not always obvious to the compiler if some referenced variable or some code is ever going to be used or executed.

So, yeah, these days, most of clearly unused stuff is removed.

Alexey Frunze
  • 61,140
  • 12
  • 83
  • 180
  • 1
    It depends on the unused stuff. Anything at global scope (and that includes most functions) can only be removed by the linker, and the granularity of most linkers is the object file, so as soon as the object file is incorporated into your program, you get everything that is in it. Typically, all that will get removed is local variables and such; things that don't require many resources anyway. – James Kanze Apr 03 '13 at 09:03
  • @JamesKanze I did mention linkers. The granularity doesn't have to be a single object file (translation unit). – Alexey Frunze Apr 03 '13 at 09:06
  • 1
    It doesn't have to be, but it almost always is. In practice, there's a reason why experienced programmers tend to put each function in a separate source file when constructing library code. – James Kanze Apr 03 '13 at 09:11
  • @JamesKanze I guess few people (except those who write standard libraries and put functions into separate files) really care enough and that's why this remnant of the past continues to exist. There's no technical difficulty here. The relevant code just needs to be written. – Alexey Frunze Apr 03 '13 at 09:18
  • If you're talking about the relevant code in the linker... The real issue, I think, is modifying the object format so that the necessary information is present. The linker normally only sees the symbols (and in most object formats, there's no guarantee that the code for a given function be contiguous). The problem isn't writing the relevant code; it's providing the necessary information to the linker. – James Kanze Apr 03 '13 at 11:12
  • @JamesKanze That's largely a coding problem. We've got as far as link-time optimization, which includes code generation/manipulation, not just address fix-ups. It's just another step in a similar direction. – Alexey Frunze Apr 03 '13 at 11:24
  • @JamesKanze, the "one function per file" comes from the days of static libraries, the linker grabbed the `.o` out of the `.a` if some symbol in it was used, to include in the executable. – vonbrand Apr 04 '13 at 20:28
  • @vonbrand That's still the usual practice today. It's only the system libraries (and libraries which are assimilated to system libraries, like a data base interface) that you want to link dynamically. – James Kanze Apr 05 '13 at 07:58