Thread: When to use a .cpp file

  1. #1
    Registered User
    Join Date
    Apr 2004
    Posts
    72

    When to use a .cpp file

    Say you declare your class in a header file. Some member functions are big, some medium, some small, and some with a single line (public accessor). My book suggests that professional code tend to have the smaller code within the header, and the bigger functions are defined within its equivalent .cpp file. Is that really common practice? I know some people who are religious with putting everything in a cpp file. Is this really the common way to do things? It would save space in the cpp file anyway.

  2. #2
    The larch
    Join Date
    May 2006
    Posts
    3,573
    It is usually a good idea to put implementations in a separate file. However, it is reasonable to have the small functions inlined, therefore they need to be in the header anyway.

    Note that inlining large functions usually reduces performance (as far as I've seen).

    Compilers also mostly don't support putting templated code in a separate cpp file.

    Edit: One more thing. You can put the code that needs to be in the header (for inlining or templates) in a separate file and include that at the end of the header file. That's for organizational purposes only: the preprocessor will just paste that file into the header. It may also have a different extension, for example "*.tpp" for template code implementations.
    Last edited by anon; 07-25-2007 at 05:13 AM.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  3. #3
    Registered User
    Join Date
    Apr 2004
    Posts
    72
    Makes sense... I'm finding out that's the only way to inline small member functions. It would be a mistake to just throw small member functions in the .cpp file and claim professional code, unless he's building a word processor . How many lines are usually the safe limit for inline functions? I'm thinking 1-20.

  4. #4
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Maybe 1?
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  5. #5
    Registered User
    Join Date
    Apr 2004
    Posts
    72
    Hmm, I guess macros were no different. Its rare to see a macro with over three lines. Zeroing memory from a structure, etc. Probably faster in a real-time loop with a macro/inline function than calling it every frame.

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Apart from 1-line set/get type functions, put everything in the .cpp file until you've got a working and debugged program.

    Then you can work out whether there is any impact of performance / code bloat by careful measurement of a known working and stable system.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    Apr 2004
    Posts
    72
    Good idea... thanks for the tips everyone. I'll keep it to one line and go from there.

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Inlining is a way to make code run faster, but it's only meaningfull if the inlined code is quite short. And it really only makes sense in code that is run often - accessor methods are of course a typical case where inlining makes sense.

    In an ideal case, the inlined code should be shorter than the "out of line" code.

    Note also that adding inline to a function doesn't alway make it inlined:
    1. functions that you take the address of can't be inlined.
    2. Virtual methods can't be inlined.
    3. Most compilers have a limit (can sometimes changed by compiler flags - but this is only really useful if you have a good reason to do so, benchmarks showing that it's faster that way would be a good way to determine that).
    4. Code that the compiler "can't see" will never be inlined, so even if you add "inline" in a .cpp file that is compiled separately from another file, it won't inline the code.

    There are several cases where aggressive inlining is NOT faster than the non-inlined code. One well-known case where "reducing the inlining makes better code" is in the Linux kernel, where they went from "maximum inlining" to "minimum inlining" and actually saw some benefits [I can't remember the exact difference, but system calls were generally faster after this change].

    Also be aware that if you inline a function into a another inlined function, it can cause much bigger code, so it's GENERALLY not a good idea to inline functions that call other functions - exceptions do exist, but it's a good starting point to avoid this.

    --
    Mats

  9. #9
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by philvaira View Post
    Say you declare your class in a header file. Some member functions are big, some medium, some small, and some with a single line (public accessor). My book suggests that professional code tend to have the smaller code within the header, and the bigger functions are defined within its equivalent .cpp file. Is that really common practice? I know some people who are religious with putting everything in a cpp file. Is this really the common way to do things? It would save space in the cpp file anyway.
    Most intelligent modern C++ compilers make their own decisions whether to inline functions. Defining a function inside a class definition may result in an inline function, or maybe not. The compiler is generally better at determining what should be inlined than you are.

    So, in theory, you could write every function of a class inline, and allow the compiler to decide which functions are simple enough to actually produce inline code. It's tempting, but there's a big down side -- header files are included by every .cpp file that uses the functionality exported by that header file. This means the code in that header file is recompiled over and over again, and this can be incredibly slow.

    I wouldn't worry too much about accidentally hurting performance by declaring functions inline. The compiler won't inline it if it shouldn't be inlined.

  10. #10
    The larch
    Join Date
    May 2006
    Posts
    3,573
    I wouldn't worry too much about accidentally hurting performance by declaring functions inline. The compiler won't inline it if it shouldn't be inlined.
    Wouldn't that depend on the compiler? And would it even be possible to inline stuff if you haven't written the code in a particular way (having method implementation inside the class declaration for example)?

    I'm working on a largish program where certain parts need to be as fast as possible. As an idea I tried inlining a fairly large function that gets called very often, by moving the definition inside the class declaration. If I'm not wrong compiler optimizations were on and obviously the compiler did something different as there was a large speed ... decrease.

    (Fortunately I stumbled upon an higher-level implementation idea that will give it a big boost )
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  11. #11
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Compilers do have their own ideas of what to inline and what not to inline. The keyword inline isn't necessarily observed by the compiler - many compilers do have a switch to say "inline when you think it's a good idea" as well as a switch for "inline things that have the inline keyword" (and of course a switch for "inline nothing" - which is a good idea for debugging - as inlined code often breaks the debuggers ability to understand where in the code you are at the mome).

    My personal opinion is that unless you REALLY KNOW what you're doing, avoid worrying about inline at all.

    A comment to anon: Is it possible that the compiler did exactly what you wanted it to do: inlined the big function. But because it was inlined, the code grew too large to fit in the L1 cache easily, and thus you got worse performance?

    --
    Mats

  12. #12
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Yes, that's what I would guess.

    I brought this up as an example where the compiler didn't know better than me. Of course, I usually don't bother about this kind of optimisations, so I don't know if there are some additional compiler switches to -O2 or -O3.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  13. #13
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Sometimes the -Os (both MS VC (cl) and gcc's flag for "optimize for smallest codesize") gives the best performance, because smallest code is inlined when inline makes it smaller, and not inlined if the code is larger after inline than before. And smallest code fits best in cache, frequently used functions can remain in cache, rather than being a "different" copy of the function when it's being inlined, etc, etc. It's worth giving it a try, that's for sure.

    I'm pretty sure gcc has various switches for the limits of how much code to inline/not inline, etc. MS VC (cl) doesn't seem to support changing the inline limits other than the three levels of "inline nothing", "inline only functions marked inline", "inline what the compiler thinks will work".

    --
    Mats

  14. #14
    Registered User
    Join Date
    Apr 2004
    Posts
    72
    Yip, I know this stuff... could be great for someone else though if they are a little rusty. I do a lot of real-time applications so I'm trained to add performance even though it might make an application a little bigger in memory. Padding structures is another example so they are 32-bit aligned. A lot of time, there's clearing memory, getting user input, etc. These small functions are inlined because the function overhead is probably longer in milliseconds than the 1-2 lines of code!

  15. #15
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by philvaira View Post
    Padding structures is another example so they are 32-bit aligned.
    You are aware that the compiler pads the structures for you, right?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. File transfer- the file sometimes not full transferred
    By shu_fei86 in forum C# Programming
    Replies: 13
    Last Post: 03-13-2009, 12:44 PM
  2. Problems passing a file pointer to functions
    By smitchell in forum C Programming
    Replies: 4
    Last Post: 09-30-2008, 02:29 PM
  3. System
    By drdroid in forum C++ Programming
    Replies: 3
    Last Post: 06-28-2002, 10:12 PM
  4. Hmm....help me take a look at this: File Encryptor
    By heljy in forum C Programming
    Replies: 3
    Last Post: 03-23-2002, 10:57 AM
  5. Need a suggestion on a school project..
    By Screwz Luse in forum C Programming
    Replies: 5
    Last Post: 11-27-2001, 02:58 AM