8

Possible Duplicate:
Inline functions in C++

What does the compiler do if I completely implement a class in its header file? A typical example follows:

class MyException
{    
public:
    explicit MyException(const char* file, int line) file(file), line(line) {};
    const char* getFile() const { return file };
    int getLine() const { return line };
private:
    const char* const file;
    const int line;
};

My intention is to use the class like this: throw MyException(__FILE__, __LINE__).

I include this header file into each .cpp file. I suppose the compiler will compile the class as many times as it is defined and include the (identical) machine code into every object file it produces. Now, what will the linker do? I tried a simpler example (without all those pesky const's) and it compiled fine.

What would happen, if instead of a simple class, I implemented a three-screenful-long C function in a header file? And the final question, should I split my example into .h and .cpp files?

Community
  • 1
  • 1
peter.slizik
  • 2,015
  • 1
  • 17
  • 29
  • 7
    Methods implemented in the class definition are inline. – Luchian Grigore Sep 04 '12 at 09:13
  • 1
    For a short class like this it does not make sense to split it up into .h and .cpp. – alfa Sep 04 '12 at 09:14
  • 1
    It will go through fine, as long as you do not include your exception in 2 libraries and throw this execption accross the library boundaries on a Linux system. The runtime will consider the 2 version of the exception as different and a catch(MyException &) in library A might not work for a throw MyException from library B – gastush Sep 04 '12 at 09:16
  • 1
    A similar question: http://stackoverflow.com/questions/2501776/inline-functions-in-c – jrok Sep 04 '12 at 09:20
  • something like this will happen - http://xkcd.com/292/ – Abyx Sep 04 '12 at 09:29

3 Answers3

6

All methods will be inline methods. You may loose some minimal time on the overall compilation, but it's ok. As far as I know the only problem that can occur is if you have a static non-cost member variable. Then you have to assign a storage place for it (place a definition and and initial value if you want) presumably in a .cpp or else you will get linker errors about multiple definition.

I've seen header-only projects which had only the main() function in a CPP, but that was heavily templated.

Update for C++17: You can declare static non-const members as inline in your header file since C++17. This makes header-only libraries easily possible without gymnastics like static variables inside inline functions.

Notinlist
  • 16,144
  • 10
  • 57
  • 99
  • This "only problem" has been resolved by C++17's inline variables. They collapse into one instance like inline functions. It seems to work with dynamic linking as well, but there is some debate that it is defined by the standard or just accidental. https://stackoverflow.com/questions/51374558/are-inline-variables-unique-across-boundaries – Notinlist Feb 14 '21 at 14:58
4

A class definition itself doesn't produce any code. It just shows users of the class how it is layed out, so they can generate appropriate code to manipulate it.

It's the member functions of the class that generate code. When you define a member function inside the class definition it gives the function an implicit inline declaration.

A function call can be compiled and linked in one of two ways:

(1) A single copy of the function code with a RETURN assembly instruction at the end can be placed in the image, and a CALL assembly instruction can be placed (along with param passing and return value transfer) at the call site to transfer control to this code.

or

(2) An entire copy of the function implementation can replace the entire function call at the call site.

A function declared inline is a recommendation to the compiler to do it the second way. Further an inline declaration allows the function to be defined in several translation units (so it can be placed in a shared header file). In order for the compiler have the option of implementing the second method, it needs a copy of the function implementation at compile-time. This isn't available if the function implementation is in a foreign translation unit.

It should also be noted that modern compilers do complicated things with functions declared inline. See:

http://gcc.gnu.org/onlinedocs/gcc/Inline.html

Andrew Tomazos
  • 66,139
  • 40
  • 186
  • 319
  • 2
    There's a subtle difference between an inline function and an inlined function. – Luchian Grigore Sep 04 '12 at 09:18
  • It's important to add that inline functions _may_ be expanded inline. Not they _will_ be... But non inline functions may also be expanded inline too. – jcoder Sep 04 '12 at 09:42
  • 1
    The more important meaning of `inline` is that the function may be defined in multiple translation units and the compiler/linker/whatever is required to produce just one copy in the final program. That is directly relevant to the question (since the class members are implicitly inline, and therefore the class definition can be included from multiple translation units), while any effect it might have on the decision to inline particular function calls is not relevant. – Mike Seymour Sep 04 '12 at 11:11
4

When you implement member functions inside a header file, all those functions become implicitly inline.

What does this mean and what implications does it have?

As per, C++03 Standard §7.1.3/4:

  • It hints the compiler that substitution of function body at the point of call is preferable over the usual function call mechanism.
  • Even if the inline substitution is omitted, the other rules(especially w.r.t One Definition Rule) for inline are followed.

So Yes, every translation unit will have the definition of the inline function.This may result in increase in the size of your binaries.

Usually any good mainstream compiler will substitute function body at the point of call if needed, so marking functions inline merely for #1 is not really a good idea but if you want to make your intent clear to users of your class then you can do so by defining the functions within the header or explicitly marking your functions as inline.

Should I split my example into .h and .cpp files?

Yes, that is the usual compilation model that most of the projects use, wherein you separate the interface(.h) from the implementation(.cpp).The interfaces are shared with the users of your code as header files while the implementation is provided in the form of binaries.To some extent this provides a safeguard to your intellectual property.
This is known as the Separation Model.

C++ projects using templates will usually use the Inclusion Model rather than the Separation Model of usual C++ projects.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • What happens when the compiler compiles the std library? Do they produce *.obj files or all of the std template definitions will have each copy on .obj file for a .cpp that includes them? – acegs Oct 19 '18 at 00:54