Dollarslice
Dollarslice

Reputation: 10284

Inline keyword vs header definition

What's the difference between using the inline keyword before a function and just declaring the whole function in the header?

so...

int whatever() { return 4; }

vs

.h:

inline int whatever();

.cpp:

inline int myClass::whatever()
{
    return 4;
}

for that matter, what does this do:

inline int whatever() { return 4; }

Upvotes: 26

Views: 11440

Answers (5)

Mike Seymour
Mike Seymour

Reputation: 254431

The purpose of inline is to allow a function to be defined in more than one translation unit, which is necessary for some compilers to be able to inline it wherever it's used. It should be used whenever you define a function in a header file, although you can omit it when defining a template, or a function inside a class definition.

Defining it in a header without inline is a very bad idea; if you include the header from more than one translation unit, then you break the One Definition Rule; your code probably won't link, and may exhibit undefined behaviour if it does.

Declaring it in a header with inline but defining it in a source file is also a very bad idea; the definition must be available in any translation unit that uses it, but by defining it in a source file it is only available in one translation unit. If another source file includes the header and tries to call the function, then your program is invalid.

Upvotes: 10

Matthieu M.
Matthieu M.

Reputation: 299760

There are several facets:

Language

  • When a function is marked with the inline keyword, then its definition should be available in the TU or the program is ill-formed.
  • Any function defined right in the class definition is implicitly marked inline.
  • A function marked inline (implicitly or explicitly) may be defined in several TUs (respecting the ODR), whereas it is not the case for regular functions.
  • Template functions (not fully specialized) get the same treatment as inline ones.

Compiler behavior

  • A function marked inline will be emitted as a weak symbol in each object file where it is necessary, this may increase their size (look up template bloat).
  • Whereas the compiler actually inlines the call (ie, copy/paste the code at the point of use instead of performing a regular function call) is entirely at the compiler's discretion. The presence of the keyword may, or not, influence the decision but it is, at best, a hint.

Linker behavior

  • Weak symbols are merged together to have a single occurrence in the final library. A good linker could check that the multiple definitions concur but this is not required.

Upvotes: 29

justin
justin

Reputation: 104698

without inline, you will likely end up with multiple exported symbols, if the function is declared at the namespace or global scope (results in linker errors).

however, for a class (as seen in your example), most compilers implicitly declare the method as inline (-fno-default-inline will disable that default on GCC).

if you declare a function as inline, the compiler may expect to see its definition in the translation. therefore, you should reserve it for the times the definition is visible.

at a higher level: a definition in the class declaration is frequently visible to more translations. this can result in better optimization, and it can result in increased compile times.

unless hand optimization and fast compiles are both important, it's unusual to use the keyword in a class declaration these days.

Upvotes: 10

Tony Delroy
Tony Delroy

Reputation: 106076

If you are linking multiple objects into an executable, there should normally only be one object that contains the definition of the function. For int whatever() { return 4; } - any translation unit that is used to produce an object will contain a definition (i.e. executable code) for the whatever function. The linker won't know which one to direct callers to. If inline is provided, then the executable code may or may not be inlined at the call sites, but if it's not the linker is allowed to assume that all the definitions are the same, and pick one arbitrarily to direct callers to. If somehow the definitions were not the same, then it's considered YOUR fault and you get undefined behaviour. To use inline, the definition must be known when compiler the call, so your idea of putting an inline declaration in a header and the inline definition in a .cpp file will only work if all the callers happen to be later in that same .cpp file - in general it's broken, and you'd expect the (nominally) inline function's definition to appear in the header that declares it (or for there to be a single definition without prior declaration).

Upvotes: 1

Cray
Cray

Reputation: 2454

This question explains a lot about inline functions What does __inline__ mean ? (even though it was about inline keyword.)

Basically, it has nothing to do with the header. Declaring the whole function in the header just changes which source file has that the source of the function is in. Inline keyword modifies where the resulting compiled function will be put - in it's own place, so that every call will go there, or in place of every call (better for performance). However compilers sometimes choose which functions or methods to make inline for themselves, and keywords are simply suggestions for the compiler. Even functions which were not specified inline can be chosen by the compiler to become inline, if that gives better performance.

Upvotes: 3

Related Questions