81

Why should I do something like this:

inline double square (double x) { return x * x; }

instead of

double square (double x) { return x * x; }

Is there a difference?

Jan Schultke
  • 17,446
  • 6
  • 47
  • 96
Pwnna
  • 9,178
  • 21
  • 65
  • 91
  • 1
    possible duplicate of [Inline functions vs Preprocessor macros](http://stackoverflow.com/questions/1137575/inline-functions-vs-preprocessor-macros) – Steve Jessop May 12 '11 at 00:16
  • 2
    Actually there are a lot of dupes and near-dupes: http://stackoverflow.com/search?q=c%2B%2B+inline. Some of the answers are better than others, some of them falsely state that the `inline` keyword causes the function to be inlined at all call sites, and so on. That may not be the closest dupe. – Steve Jessop May 12 '11 at 00:18
  • 1
    Also see [Inline Functions](http://www.parashift.com/c++-faq-lite/inline-member-fns.html) in the C++ FAQ. They have a very good treatment of inline. – jww Jul 23 '19 at 03:57

6 Answers6

93

The former (using inline) allows you to put that function in a header file, where it can be included in multiple source files. Using inline makes the identifier in file scope, much like declaring it static. Without using inline, you would get a multiple symbol definition error from the linker.

Of course, this is in addition to the hint to the compiler that the function should be compiled inline into where it is used (avoiding a function call overhead). The compiler is not required to act upon the inline hint.

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • 2
    I thought the purpose of inline is for the compiler to 'expand' the content of the function where it is called, so there won't be vtable lookup (or instruction jump to the function on the CPU level). – DJ. May 11 '11 at 23:41
  • Is your first point a [useful] side-effect of the intended purpose? – Ian Fleeton May 11 '11 at 23:50
  • @Ian Fleeton: It is indeed a side-effect; if an inline identifier did not have file scope, then it would be impossible to put an inline function definition in a header file at all. – Greg Hewgill May 11 '11 at 23:52
  • @DJ: Used to be. Modern compilers have no reason to care what the programmer thinks about what should be inlined. – GManNickG May 11 '11 at 23:52
  • @Ian: It is a side-effect, but it's the only important effect, since the "intended purpose" can be done automatically by the compiler. – Ben Voigt May 11 '11 at 23:53
  • 12
    @Greg: It doesn't really act like it was `static`. If it did, each translation unit would have it's own ownership over its copy of the function, and the linker would treat them all as different functions (which happened to have the same name). Contrarily, `inline` instructs the linker that, should it see different definitions of this function, they are all the same and must be merged into one. But ignoring that detail, it does, for the most part, behave as if it were `static`. – GManNickG May 11 '11 at 23:54
  • 1
    @DJ: `inline` can't prevent vtable lookup, you need *call devirtualization* for that. – Ben Voigt May 11 '11 at 23:54
  • Is any of this noted in the C++ standard? – Daniel Jour May 13 '15 at 12:20
  • What do you mean by this - `Using inline makes the identifier in file scope` ? – skpro19 May 16 '21 at 10:11
31

On a modern compiler there is likely not much difference. It may be inlined without the inline and it may not be inlined with the inline.

Ben Jackson
  • 90,079
  • 9
  • 98
  • 150
27

Yes there is a difference. https://isocpp.org/wiki/faq/inline-functions.

When you specify that a function is inline you are causing the compiler to put the code of the method in where ever it is being called.

void myfunc() {
  square(2);
}

is identical to

void myfunc() {
   2 * 2;
}

Calling a function is good for code clarity, but when that function is called the local state has to be pushed to the stack, a new local state is setup for the method, and when it is done the previous state needs to be popped. That is a lot of overhead.

Now if you up your optimization level, the compiler will make decisions like unrolling loops or inlining functions. The compiler is still free to ignore the inline statement.

default
  • 11,485
  • 9
  • 66
  • 102
Erik Nedwidek
  • 6,134
  • 1
  • 25
  • 25
6

From "Inline function" on Wikipedia:

Inline function is a function upon which the compiler has been requested to perform inline expansion.

In other words, the programmer has requested that the compiler insert the complete body of the function in every place that the function is called, rather than generating code to call the function in the one place it is defined. Compilers are not obligated to respect this request.

cafce25
  • 15,907
  • 4
  • 25
  • 31
johannesMatevosyan
  • 1,974
  • 2
  • 30
  • 40
2

inline works well with the concept of procedural abstraction:

inline double square (double x) { return x*x;}

int squareTwice(double x) {
    double first = square(x);
    double second = square(x);
    return first * second; 
}

The above is fundamentally similar to the following:

int squareTwice(double x) {
    double first = x*x;
    double second = x*x;
    return first * second; 
}

This happens because when the compiler inline-expands a function call, the function's code gets inserted into the caller's code stream; therefore, it may be easier to procedurally abstract the second example to the first example.

Procedural abstraction makes it possible to break up a routine into smaller subroutines that are much easier to read (although this can be a style choice).

Gio Borje
  • 20,314
  • 7
  • 36
  • 50
1

The inline function, if the compiler complies, will include the inline function in the code in which it was called as if no function was called (as though you had put the logic in the calling function) and avoid the function call overhead.

Ian Fleeton
  • 1,157
  • 8
  • 14
  • 6
    The compiler doesn't have to inline the function if it doesn't want to, even if the inline keyword is specified. – Marlon May 11 '11 at 23:40
  • 1
    @Alex Marlon did not say that the compiler **wouldn't** inline the function, merely that it **doesn't have to**. Those are very different things. – Michael Dorst Aug 14 '14 at 03:14