c++optimizationheader-files

Placing methods in .h vs. .cpp files


I've seen code for a class placed into a separate C++, while the method definitions are placed in the header file. My 1st OOP experience is with Java, in which all the methods are placed in the class file, and I actually prefer this.

Does placing all my methods in a header file affect the assembly code generated by the compiler, or not?

And if so, is it detrimental to performance at all to place the entire code of a class in its header file?


Solution

  • There're a few valid reasons for header/implementation splitting and separate compilation:
    1. That may be a job requirement - for example, you're supplying a binary library + header to somebody, or your colleagues are too conservative to accept anything else.
    2. Its still required to develop very large projects (say, >10M of source), because rebuilding the whole app after each modification would become painful. (But it should be still ok to compile something like jpeglib or zlib as a single module)
    3. There's an opinion that its easier to use header files as reference, to look up functions and such. (But normally its better to write a proper documentation; unlike headers, bugs in documentation are less likely to affect your program)

    Also, there're much more reasons to not use it anymore:
    1. You'd like to avoid maintaining the duplicate code.
    2. Class methods don't need forward declarations
    3. Templates can only be declared in headers anyway
    4. Cases where you don't need function inlining are actually fairly rare, ie calling large functions multiple times in a tight loop, but there're noinline attibutes and PGO for that. Otherwise inlining improves speed. And as to code bloat, most libraries are already huge anyway.
    5. Overall, programs compiled as a single source are faster and smaller, because the compiler can do a better job.
    6. Without headers, the source would be frequently around twice smaller, and compiler would be able to properly check the syntax, so you won't be able to accidentally link an extern "C" cdecl function prototype to a variable as implementation. Also overall, it would be more portable, because different linkers have different ideas about name matching.
    7. Its weird, but dynamic allocation is frequently used only because of header style - dependencies could be resolved automatically by defining all the details within a single class, but people prefer to use pointers to partial class declarations instead (and then hunt memory leaks).

    Now, a few bonus points for separate object modules:
    4. PGO stats in gcc are generated per object module, which seems to be the only way to "benchmark" a few different operation modes with a single executable.
    5. Its possible to compile different modules with different compiler options for speed optimization. There're also some compiler extensions for that, but they're not very reliable.
    6. Sometimes a compiler can do something weird to another part of code when you modify something - but usually it can't propagate outside of an object module.