21

According to the wikipedia C++ article

C++ is designed to give the programmer choice, even if this makes it possible for the programmer to choose incorrectly.

If it is designed this way why there is no standard way to force the compiler to inline something even if I might be wrong?

Or I can ask why is inline keyword is just a hint?

I think I have no choice here.

In the OOP world we call methods on the objects and directly accessing members should be avoided. If we can't force the accessors to be inlined, then we are unable to write high performance but still maintainable applications.

(I know many compilers implement their own way to force inlining but it's ugly. Using macros to make inline accessors on a class are ugly too.)

Does the compiler always do it better than the programmer?

Calmarius
  • 18,570
  • 18
  • 110
  • 157
  • 7
    Compilers do some crazy optimization stuff, and inlining trivial accessors are the basics of the basics. – Xeo May 24 '11 at 09:37
  • 4
    What reason do you have to believe you could ever choose better than the compiler? It knows a lot more about CPU instruction ordering, pipeline stalls, etc than you probably do. – SoapBox May 24 '11 at 09:37
  • 5
    With regards to your last question, almost always... – Nim May 24 '11 at 09:38
  • 3
    There is no standard way, because there is no way to force inlining. (Why is there no _standard_ way to make pigs fly?). There situations when a compiler could not be able to inline a function, no matter how many times you force it to. – sehe May 24 '11 at 09:42
  • 1
    Was `inline` really intended as only a hint and not an order originally? This is the language with the `register` keyword... it was originally designed for much weaker optimizing compilers than we have now. – Baffe Boyois May 24 '11 at 10:00
  • 1
    @Baffle: Unless C [or whichever of its inspirations brought us `inline` to begin with] did not support recursive calls at some point, it is safe to assume `inline` has always been a hint. – Dennis Zickefoose May 24 '11 at 10:14
  • @Calmarius: The compiler can do what it likes, delete your variabes and functions, add new ones, rearrange your code etc. etc. As long as the sequence of system calls and read/writes to volatile variables remains the same. So I'm afraid you have much less control than you think you have. In general the compiler does do a better job. If you really care about these issues then you should program in assembler. – john Aug 28 '11 at 06:08
  • 3
    @SoapBox: It's not that hard to find situations where inlining helps, but the compiler isn't detecting it. Happens to me often enough. Compiler writers (and their compilers) aren't stupid, but neither are the people who ask these questions. – user541686 Aug 18 '12 at 13:30
  • I think a standard way to force inline would be useful. Everything that allows you to avoid macros and get the type safety of functions is a good thing, IMHO. Also fits the bill with C++ as a better C. – Erik Alapää Mar 06 '17 at 14:37

5 Answers5

18

How would a compiler inline a recursive function (especially if the compiler does not support Tail-call optimization and even if it does, the function is not Tail-call optimize-able).

This is just one reason where compiler should decide whether inline is practical or not. There can be others as well which I cant think of right now.

Aamir
  • 14,882
  • 6
  • 45
  • 69
5

Does the compiler always do it better than the programmer?

No, not always... but the programmer is far more error prone, and less likely to maintain the optimal tuning over a span of years. The bottom line is that inlining only helps performance if the function is really small (for at least one common/important code path) but then it can help by about an order of magnitude, depending on many things of course. It's often impractical for the programmer to assess let alone keep a careful eye on how trivial a function is, and the thresholds can vary with compiler implementation choices, command line options, CPU model etc.. There are so many things that could suddenly bloat a function - any non-builtin type can trigger all sorts of different behaviours (esp in templates), use of an operator (even new) can be overloaded, the verbosity of calling conventions and exception-handling steps aren't generally obvious to the programmer.

The chances are that if the compiler isn't inlining something that's small enough for you to expect a useful performance improvement if it was inlined, then the compiler's aware of some implementation issue you're not that would actually make it worse. In those gray cases where the compiler might go either way and you're just over some threshold the performance difference isn't likely to be significant anyway.

Further, some programmers (myself included) can be lazy and deliberately abuse inline as a convenient way to put implementation in a header file, getting around the ODR, even though they know those functions are large and that it would be disastrous if the compiler (were required to) actually inline them. This doesn't preclude a forced-inline keyword/notation though... it just explains why it's hard to change the expectations around the current inline keyword.

Tony Delroy
  • 102,968
  • 15
  • 177
  • 252
  • 1
    I don't think that's an abuse of the keyword. – GManNickG May 24 '11 at 10:44
  • @GMan, @Matthieu: given `inline` was definitely introduced to convey a hope or expection of inlining, then using it purely to avoid ODR sure seems like an abuse to me - doesn't mean I haven't done it now and then too... :-). It may even be that such creeping abuses are the main reason for the now relaxed "if the compiler feels like it" impact of the keyword...? – Tony Delroy May 24 '11 at 16:42
  • 1
    What? Wasn't `inline` added specifically because of ODR? – Thomas Eding Feb 25 '12 at 02:16
  • @TonyD: I thought it was added to declare that the code is inline in the header. – Mooing Duck Mar 26 '14 at 20:42
  • @MooingDuck: in modern C++ it has utility for that purpose - allowing the compiler to differentiate between intentional out-of-line invocation - to be resolved at link time - and an accidentally omitted definition warranting a C.T. error, but in the evolution of C/C++ that was initially controlled with the `extern` keyword, with inlining done first with macros then `inline` a fix for the type safety, side effects, lack of recursion and other evils of macros. – Tony Delroy Mar 27 '14 at 01:33
3

Or I can ask why is inline keyword is just a hint?

Because you "might" know better than the compiler.

Most of the time, for functions not marked inline (and correctly declared/defined), the compiler, depending on it's configuration and implementation, will itself evaluate if the function can be inlined or not.

For example, most compilers will automatically inline member functions that are fully defined in the header, if the code is'isn't long and/or too complex. That's because as the function is available in the header, why not inline it as much as we can? However this don't happen, for example, in Debug mode for Visual Studio : in Debug the debug informations still need to map the binary code of the functions, so it avoid inlining, but will still inline functions marked inline, because the user required it. That's useful if you want to mark functions yuo don't need to have debug-time informations (like simple getters) while getting better performance at debug-time. In Release mode (by default) the compiler will agresively inline everything it can, making harder to debug some part of the code even if you activate debugging informations.

So, the general idea is that if you code in a way that helps the compiler inlining, it will inline as much as it can. If you write your code in ways that is hard or impossible to inline, it will avoid. If you mark something inline, you just tell the compiler that if it find it hard but not impossible to inline, it should inline it.

As inlining depends on both contexts of the caller and the callee, there is no "rule". What's often advised is to simply ignore explicitly mark function inline but in two cases :

  1. if you need to put a function definition in a header, it just have to be inlined; often the case for template (member or not) functions, and other utility functions that are just shortcuts;
  2. if you want a specific compiler to behave in specific way at compile time, like marking some member functions inline to be inlined even in Debug configuration on Visual Studio compilers, for example.

Does the compiler always do it better than the programmer?

No, that's why sometimes using the inline keyword can help. The programmer can have sometimes a better general view of what's necessary than the compiler. For example, if the programmer wants it's binary to be the smallest possible, depending on code, inlining can be harmful. In speed performance required application, inlining aggressively can help very much. How would the compiler know what's required? It have to be configured and be allowed to know in a fine-grain way what is really wanted to be inline.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Klaim
  • 67,274
  • 36
  • 133
  • 188
0

Mistaken assumption.

There is a way. It's spelled #define. And for many early C projects, that was good enough. inline was sufficiently different - hint, better semantics - that it could be added besides macros. But once you had both, there was little room left for a third option in between, one with the nicer semantics but non-optional.

MSalters
  • 173,980
  • 10
  • 155
  • 350
-1

If you really need to force the inline of a function (why?), you can do it: copy the code and paste it, or use a macro.

Loghorn
  • 2,729
  • 17
  • 22