Home > Software engineering >  Do forward declarations disable any runtime optimizations?
Do forward declarations disable any runtime optimizations?

Time:08-05

We can forward declare a function:

void func1();

void func2() {
    // use func1
}

void func1() {
    // do stuff
}

This may be necessary if func1 calls func2:

void func1();

void func2() {
    func1();
}

void func1() {
    if (condition) {
        func2();
    }
}

While inlining func1 in the second example wouldn't be difficult, I do not know if in arbitrarily complicated programs there are theoretical barriers these kinds of compiler optimizations. In the second case, the forward declaration was necessary, and there may be compiler optimizations lost related to the recursive nature of the program.

Question: When forward declarations are not necessary but still used (e.g., the first example), are any compiler optimizations lost on any of the major compilers (gcc, clang, msvc)?

CodePudding user response:

To the best of my knowledge, redundant forward declarations do not inhibit any compiler optimizations. At worst, they present a couple extra tokens for the compiler to read and process and then discard (negligible). There are situations where forward declarations can change the meaning of the code that follows and in such a situation that could, of course, have follow on effects on the compilers optimizer (but in such a case you are probably wanting the behaviour change, so not much you can do - it might even be a positive effect).

CodePudding user response:

Forward declaring a function in the same translation unit (that is, the same cpp file) will not have any effect on performance. Modern compilers typically go through several passes (look into LLVM’s API if you’re interested) and will be able to see the definition, regardless of declarations, when generating backend instructions.

If functions are declared in multiple translation units, a compiler may or may not perform optimizations across unit boundaries. A compiler compiles each source file as a different translation unit, and, once all source files have been compiled as individuals (with only one source file containing the function definition) links them together. Optimizations between translation units is known as link-time optimization (LTO) and may or may not be enabled by default.

Ultimately, however, this should not be a significant concern. This sounds like a case of premature optimization — ideally, you should make a reasonable effort to write decent code, and optimize only when measured performance is below desired. Otherwise you’re likely to spend a significant amount of time trying to fix something that isn’t broken.

  • Related