6

Reading an old answer on When should I write the keyword 'inline' for a function/method? that says:

It is said that inline hints to the compiler that you think the function should be inlined. That may have been true in 1998, but a decade later the compiler needs no such hints. Not to mention humans are usually wrong when it comes to optimizing code, so most compilers flat out ignore the 'hint'.

This answer was posted in 2009 so I want to figure it finally out:

  1. Do modern c++11-compatible compilers always ignore inline hints specified by user and do this only automatically?
  2. Do inline hints only stay to provide backward compatibility?
  3. If not 1. so this answer is incorrect?
Community
  • 1
  • 1
VP.
  • 15,509
  • 17
  • 91
  • 161
  • 1
    @iammilind So, answer on your question shows that `clang` don't ignore the hint that makes the [current answer](http://stackoverflow.com/a/1759575/1750757) wrong because nowadays at least `clang` is still searching for the `inline` keyword and make some decisions. – VP. Aug 17 '15 at 10:22
  • Yes. Ironically the answer given in Nov-2009 is more modern compared to the answer given in Nov-2014. I wish that the former were true and that was my exact assumption when I asked the question. It's quite possible that, the answer given in Nov-2014 might be an isolated scenario of Clang's limitation. Anyways, I will flag for **reopening** this question with listing the [possible duplicate](http://stackoverflow.com/questions/27042935/inline-keyword-vs-inlining-concept). – iammilind Aug 17 '15 at 10:28
  • 1
    Some compilers let you choose. MSVC, for example, has the options Don't inline anything at all, Inline just functions marked `inline`, or Inline anything that obviously should be (whether it is marked `inline` or not). – Bo Persson Aug 17 '15 at 10:44
  • 2
    You have misunderstood the answer you linked to, or not read it fully. The answer does not say `inline` is just a hint that is ignored, it says that `inline` changes the language semantics so that a function can be defined in multiple translation units. That is not only kept for backwards compatibility, it is an important property of the C++ language and the linkage model. So your whole question seems to be based on a flawed premise. `inline` is not "just a hint", it's alters how code is compiled+linked, in such a way that inlining is possible for the compiler to do (without LTO). – Jonathan Wakely Aug 17 '15 at 11:04
  • @jonathan `namespace{` also lets that happen without LTO, and is less likely to cause ODR violations. (now, `static` locals in a non LTO function you want to inline, then you still need it!) – Yakk - Adam Nevraumont Aug 17 '15 at 11:51
  • @Yakk, unnamed namespaces mean you have lots of different functions (as making the function `static` would) so it's not the _same_ function defined multiple times, it's lots of different functions defined once each. – Jonathan Wakely Aug 17 '15 at 13:31
  • @JonathanWakely sure, but it (functions in anonymous namespaces) makes inlining possible for the compiler to do without LTO or the `inline` keyword (by having distinct, yet (hopefully) identical, functions for each compilation unit). Which disagrees with your last sentence of your last comment, depending on how it is parsed: `inline` is not needed to make it possible to do inlining. There is a parsing where the last sentence means "sufficient" and not "necessary", which is maybe what you meant? – Yakk - Adam Nevraumont Aug 17 '15 at 13:33
  • @Yakk, I don't think it disagrees, I didn't say that `inline` is the _only_ way to make it possible for functions to be inlined. – Jonathan Wakely Aug 17 '15 at 13:42
  • @Yakk-AdamNevraumont `inline` is to be used in headers, anonymous namespace, not so much. – curiousguy Jun 11 '18 at 01:45
  • @curiousguy Both inline and anonymous namespaces in headers have different pitfalls. It is *really easy* to break the ODR using either inline or anonymous namespaces in headers, and using one or the other can prevent it. Most of those ODR violations are often ignored by most compilers, but make your program ill formed no diagnostic required, so I'm scared of them. – Yakk - Adam Nevraumont Jun 11 '18 at 04:01

3 Answers3

7
  1. No, they just interpret it as the standard requires, but some compilers may do nothing more than that (according to the documentation MSVC chooses based on the presence of inline keyword though, also GCC 5.1.0 takes the inline keyword into consideration when deciding).
  2. No, inline is needed to avoid duplicate symbols when linking too.

The inline keyword does have meaning, but not the meaning you may expect. It doesn't mean that the compiler must/should/might inline expand the function, that the compiler may decide to do as it sees fit, no matter if you use inline or not.

What it does mean is that you should and could repeat the function definition in every compilation unit where it is used, without resulting in linking errors - quite similar to the static keyword.

For example GCC 4.7.2 (which is perhaps not state-of-the-art, but still quite a modern compiler) seem to interpret inline no more than the standard specifies. It does not seem to inline the function if optimization is disabled and with optimization turned on it seem to inline as it likes anyway. The only difference is how the compiler handles the "outlined" function in the different cases, with inline it simply discard it or handles it in a way that would avoid duplicate symbols at link time.

skyking
  • 13,817
  • 1
  • 35
  • 57
  • 2
    I think Victor understands that `inline` is a hint, he's asking if modern compilers still take it as a hint or if they generally ignore it. – TartanLlama Aug 17 '15 at 10:02
  • 2
    That is already explained in the selected answer in the link posted in the question. – juanchopanza Aug 17 '15 at 10:03
  • If I were writing a compiler today, I'd probably use the inline keyword to choose between two options that are roughly equal in performance (inlining or not), so if the compiler can't make a firm decision which way to go, follow the hint! But that's just me. – Skizz Aug 17 '15 at 10:34
  • @VictorPolevoy Yes it's not state-of-the-art, but I wouldn't expect newer compilers to think they're less smart than that, the answer states that at least that compiler does not interpret the `inline` keyword more than the standard requires. Perhaps there are new(er) compilers that do the choice based on the `inline` keyword, but I've not seen any (maybe Microsoft does - according to the documentation they seem to do a bit at least). – skyking Aug 17 '15 at 11:06
  • @VictorPolevoy, _"Standard requires this as a hint"_, No! It requires it to allow the same function to be defined in multiple translation units, that is not "a hint" and does not mean that calls to the function should be optimised away by inlining the call. You are confusing an optimisation that is allowed (but not required) with a language keyword that affects how code is compiled+linked. They are related, but not the same. – Jonathan Wakely Aug 17 '15 at 11:06
  • 1
    @VictorPolevoy I don't see what kind of answer you want. Some compilers don't choose inlining based on the `inline` keyword and some compilers may choose based on that. – skyking Aug 17 '15 at 11:14
  • @TartanLlama, but it _isn't_ "a hint", it alters how a function is compiled and has important semantic effects. – Jonathan Wakely Aug 17 '15 at 11:25
  • @JonathanWakely you're right, I was taking too simple a view of this answer, though it was very different when I made the comment! – TartanLlama Aug 17 '15 at 11:27
  • @Yakk What do you mean by ODR pitfalls? – skyking Aug 17 '15 at 12:04
  • @skyking If two different compilation units have the same `inline` function (by name and signature) with a different implementation (due to a preprocessor token manipulation, two functions that just happen to have the same name but are not supposed to be the same, different visible overloads of some functions used within it, etc). And the result is an ill-formed program with no diagnostic required (typically, the compiler silently drops all but one implementation *at effectively random*, leading to really hard to track down bugs). – Yakk - Adam Nevraumont Aug 17 '15 at 13:32
  • 1
    @Yakk Yes, that's nasty, but I don't at the moment see how mentioning that should fit in the answer. – skyking Aug 17 '15 at 13:42
  • @skyking Thanks for the explanation, I've upvoted your answer. Seems I was lacking of understanding of some parts of `inline`. – VP. Aug 18 '15 at 08:45
3
  1. Do modern c++11-compatible compilers always ignore inline hints specified by user and do this only automatically?

C++11 is irrelevant here, the C++11 standard did not change the semantics of inline and compiler optimisations are largely independent of the language version being compiled.

  1. Do inline hints only stay to provide backward compatibility?

No, inline is not a hint, and the compiler doesn't "ignore" inline because if it did that you'd get multiple definition errors. The meaning the compiler gives to the inline keyword is not the meaning you seem to understand. It's not a hint.

If the compiler can't see the function definition it can't inline it (Link-Time Optimization changes that, but use of LTO is not very widespread yet and most libraries do not ship with LTO-enabled binaries that would allow link-time inlining).

You should read inline as "this function definition appears inline in this file" not "calls to this function should be inlined".

So the inline keyword is useful for allowing the compiler to see function definitions in multiple files, which means it is possible for it to optimise the calls away by inlining them. That doesn't necessarily make it more likely to be inlined than any other function defined in the same translation unit.

For functions that are called from multiple translation units defining the functions in headers and making them inline is necessary condition for the compiler to inline them, but it is not sufficient (because the compiler bases its inlining decisions on other conditions).

This has nothing to do with backwards compatibility, it is just as true today as in 2009.

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
  • Missing ODR danger from inline. And C++11 alternative anonymous namespace. – Yakk - Adam Nevraumont Aug 17 '15 at 11:53
  • 1
    @Yakk, why are anon namespaces a C++11 alternative? They existed in C++03 too. I didn't mention using them, or `static`, because they are different solutions, with different results, and not just a drop-in replacement for using `inline` functions. They solve a different problem (and if they _aren't_ inlined can cause significant code size increases due to all the definitions that need to be kept by the linker). – Jonathan Wakely Aug 17 '15 at 13:33
  • @VictorPolevoy, are the answers not clear? You should use the inline keyword if you want to define functions in headers without multiple definition errors. Which is exactly what the [old answer](http://stackoverflow.com/a/1759575/981959) said. What part do you not understand? It is obviously **not** useless, because if you remove the `inline` from functions defined in headers the code won't link. – Jonathan Wakely Aug 18 '15 at 08:45
  • Seriously? Define a function in a header, without `inline`. Include the header in two different files. Link the files together. – Jonathan Wakely Aug 18 '15 at 08:47
  • Is what widely used? Header files? Functions? Yes. – Jonathan Wakely Aug 18 '15 at 08:54
  • Did you even bother to read the answers or are you just wasting everyone's time? If you define it in the header file the compiler can always see the definition and so can inline it for any callers. I already answered this above though, so I'm not going to spend any more time here. – Jonathan Wakely Aug 18 '15 at 09:04
  • @JonathanWakely thank you for spending some time at me. Now I am full of shame. Probably, was reading between the lines. – VP. Aug 18 '15 at 09:07
2

C++11 compilers follow inlining hints just the same as C++03 or any edition of the language.

However, note that the inline keyword is not an inlining hint. Hints look more like __attribute__((always_inline)).

The inline keyword (or implicit inline status, which is applied to templates and such) indicates that a function is defined in a header, so the linker should expect to see multiple copies of it when combining translation units (.cpp files). It is so named because the definition must be available in order to inline a function, which means that functions in libraries need inline to practically be inlined.

Potatoswatter
  • 134,909
  • 25
  • 265
  • 421