6

C++ (and various other languages) support inline functions. If I want a function to be inlined, I have to use the inline keyword in the declaration. To me, this seams pretty unintuitive: Why can't I just use inline when calling a function? Example:

void foo(){...}
inline foo();

instead of

inline void foo(...){...}
foo();

This would allow me to inline the function in only specific places without having to duplicate the function. Also, every function could be inlined, which would make the mechanism much more flexible. Is there a reason for why this is not support?

NyxCode
  • 584
  • 1
  • 4
  • 13

3 Answers3

7

Foreword:

To inline a function i.e. the act of inlining i.e. inline expansion is an optimization where a function call is replaced by duplicated set of instructions.

To declare an inline function is to declare to the linker that the function is to be treated differently than non-inline functions. Specifically, the one-definition-rule is different for inline functions. Inline functions are allowed to be defined in multiple translation units (and in fact required to be defined in all translation units where the function is odr-used). This is different from non-inline functions, which must be defined in exactly one translation unit. The inline keyword can be used the declare an inline function.

While inline declaration is named similarly to the inlining optimization, and while former can indirectly affect whether latter is possible, these two concepts are separate.

Now, to the answer.


If I want a function to be inlined, I have to use the inline keyword in the declaration.

You don't necessarily have to use the inline keyword. A call to a non-inline function can be expanded inline by the compiler if the function is defined in the same translation unit. Even that is not a requirement for a linktime optimizer which sees all translation units.

Example:

// a.cpp
void foo(){}        // a non-inline function
inline void qux(){} // an inline function
void bar(){
    foo(); // this call to a non-inline function can be expanded inline
           // because the function is defined in the same TU
}

// b.cpp
void foo(); // the non-inline function must not be defined
            // in multiple translation units
inline void qux(){} // the inline function can and must be defined
                    // in both translation units
void xeb(){
    foo(); // this call to a non-inline function can not be expanded inline by
           // the compiler because the function is not defined in the same TU
           // the call can be expanded by a linker
    qux(); // this call can be expanded by the compiler
           // because the function is defined in the same TU
}

That said, linktime optimization isn't always an option, and function calls do happen across translation units, so inline definition is in some cases indeed necessary to allow inline expansion.

A pedantic point: A function can declared inline without the inline keyword (if it is a member function).

Why can't I just use inline when calling a function?

There just isn't such syntax in the language.

Note that the function would still have to be defined in the same translation unit or else it cannot be expanded inline by the compiler. Thus the function would still need to be declared inline if you wanted inline expansion in more than one translation unit.

I suspect that the reason why there is no syntax to force inline expansion is probably the same as why there is no way to select which branch of an if statement is the "default" branch which might have marginal effect on performance (the reasoning is just my guess in both cases): Humans are notoriously bad at optimization. I see no technical reason why such language feature couldn't be introduced. But I wouldn't expect such feature to be very useful.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • _A call to a non-inline function can be **expanded** inline by the compiler if the function is **defined** in the same translation unit._ my point: is that true even when the function has/gets multiple calls (because you said it is non-inline) – Mohammad Kanan Jan 24 '18 at 14:57
  • @MohammadKanan yes. Multipe calls can be expanded inline. – eerorika Jan 24 '18 at 15:06
  • 10x, I just read they will be shared across all translation units (static objects & variables) – Mohammad Kanan Jan 24 '18 at 15:10
  • 1
    @MohammadKanan I added clarifying foreword. Perhaps it will be of use to you. – eerorika Jan 24 '18 at 15:24
3

In C++ inline does not mean that the calls should get inlined. It means that the definition is allowed to occur in multiple translation units, whereas normally only one definition is allowed.

Since header files are usually included in many translation units of the C++ program, any function definition in a header file will end up in multiple translation units. So, to make that work, you need the inline keyword for those definitions. It's still related to inlining though, since in this case (where the definition is in the header), the definition is available at all call sites that include the header, allowing the compiler to inline it, since it knows the full definition. If only a declaration would be available in the header, inlining would only be possible during linking (with 'link time optimization' aka LTO).

Mara Bos
  • 955
  • 5
  • 11
  • what do you mean by: does not mean that the **_calls should get inlined_** – Mohammad Kanan Jan 24 '18 at 14:53
  • 1
    It means this keyword is not about substituting a function's body into the locating where the function is called. – The Techel Jan 24 '18 at 15:46
  • @TheTechel, but by definition its a suggestion to do that .. while the rest explains its properties , from point 2 in description http://en.cppreference.com/w/cpp/language/inline – Mohammad Kanan Jan 24 '18 at 18:23
  • 1
    @Mohammad - The current definition of inline does not say it is a suggestion. It only says what M-ou-se and I say it says. The standards committee simply did not want to introduce a new keyword, so instead they used "inline" which no longer meant anything at all. – Jive Dadson Jan 24 '18 at 21:00
  • @JiveDadson, in case you missed my point, its a _suggestion_ to the compiler .. Its not my _word_ .. read it in the first note here: http://www.cplusplus.com/articles/2LywvCM9/ – Mohammad Kanan Jan 24 '18 at 21:05
  • 1
    @Mohammad - cplusplus.com has too many errors, and that's one of them. Prefer cppreference.com. This gets it right: http://en.cppreference.com/w/cpp/language/inline "The original intent of the inline keyword was ..." – Jive Dadson Jan 24 '18 at 21:08
  • @JiveDadson, Yes that was my reference source in answer to TheTechel – Mohammad Kanan Jan 24 '18 at 21:12
  • @Mohammad - But it is no longer a suggestion. You're not going all backfire effect I hope. :-) Have the last word.... – Jive Dadson Jan 24 '18 at 21:18
  • @JiveDadson, :) for the most part the doc intro emphasizes _implicitly_ in-lined funcs .. so no more suggestions :) – Mohammad Kanan Jan 24 '18 at 21:23
2

Short but sweet answer: "Inline" does not do what it used to. These days, all it means is that the linker should ignore multiple definitions from separate compilation units, and just pick one and go with it. The compiler is free to do as it pleases. Most or all modern compilers ignore "inline".

Bonus fact: In the latest and greatest C++, you can declare a variable as inline.

Jive Dadson
  • 16,680
  • 9
  • 52
  • 65
  • There may be more than one definition of an inline function or variable (since C++17) in the program as long as each definition appears in a different translation unit. http://en.cppreference.com/w/cpp/language/inline – Mohammad Kanan Jan 24 '18 at 15:05
  • @MohammadKanan - I think that's what I said, – Jive Dadson Jan 24 '18 at 15:08
  • _the linker should **ignore** multiple definitions from separate compilation units._ and just pick one .. this appeared as if you mean those others won't be inlined – Mohammad Kanan Jan 24 '18 at 15:16
  • 2
    @Mohammad Appearances can be deceiving. :-) The linker does not know whether the compiler rolled a function out in-line in a given compilation unit or just never saw it. – Jive Dadson Jan 24 '18 at 20:58