0

I was going through some code at work and I found this

inline
  FLAGS get_flags(void) {
  FLAGS res;
  memset(&res, 0, sizeof(res));
  return res
}

This is declared in a header file included in the program. I realize it would be a very bad thing if it was not inlined as this is allocated on the stack. We have never had problems with the code in question, but I was just curious about it.

DavidMFrey
  • 1,658
  • 1
  • 14
  • 14
  • 2
    Whether or not this function is inlined is irrelevant to the safety of the function - you are returning res by value. – Jon Mar 31 '11 at 18:50
  • Does it matter? The call to memset() certainly won't be inlined so inlining the function would not save much. – Clifford Mar 31 '11 at 19:12
  • @Clifford: Actually, I'm pretty sure gcc inlines it with -O3, and possibly MSVC. – GManNickG Mar 31 '11 at 19:19
  • @GMan: In-lining code in an object library would require linker support for such a feature. Otherwise it would have to be a *built-in* (code directly generated by the compiler rather than from a library), or in-lined within the header file. All these may apply, but there are no guarantees - just like inlining in general. – Clifford Apr 01 '11 at 19:07
  • @Clifford: Your comment says "certainly", I object to that. Some implementations do. – GManNickG Apr 03 '11 at 22:14

6 Answers6

6

No, it is not guaranteed to be expanded inline. inline is merely a hint to the compiler.

That said, while res does indeed exist on the stack, you return a copy of it. It won't be "a very bad thing" if inline expansion doesn't occur.

James McNellis
  • 348,265
  • 75
  • 913
  • 977
2

No, it is not guaranteed that the compiler will inline it. See this answer.

As Strousoup says in The C++ Programming Language

The inline specifier is a hint to the compiler that it should attempt to generate code [...] inline rather than laying down the code for the function once and then calling through the usual function call mechanism.

Note the key word hint.

Community
  • 1
  • 1
justkt
  • 14,610
  • 8
  • 42
  • 62
2

inline has two purposes, but only one matters anymore.

As others have said, the purpose of hinting to the compiler that the function should be inlined is all but useless. The compiler is much better at determining what should be inlined than the programmer.

However, the important second use (which applies in your case) is that it breaks the one-definition rule (ODR). That is, under normal circumstances the linker must not accept seeing a symbol defined more than once. However, if that symbol was declared inline, it is free to assume the definition of each is the same and ignore the rest.

Because your function is in a header file, it might get defined in more than one translation unit, so you need to break the ODR to allow your code to compile without error.

GManNickG
  • 494,350
  • 52
  • 494
  • 543
  • [Include guards](http://en.wikipedia.org/wiki/Include_guard) should be used to prevent multiple definition in a *translation unit* in any case, and if used, then `inline` has the same effect as `static` in this context. – Clifford Apr 01 '11 at 19:11
  • @Clifford: That's partially correct. Include guards do what you say, but they won't protect you from anything in multiple translation units. However, `inline` is not the same as `static` int hat case, because `inline` allows the definitions to be merged by the linker, `static` does not. – GManNickG Apr 01 '11 at 19:23
  • @GMan: My point was that you originally said "in *a* translation unit" rather than *multiple* translation units. The difference between static and inline accepted - fair point, but whether your linker performs that optimisation is again not guaranteed, the linker would have to see that the compiler generated code was identical, which may not be the case if more than one inline having the same name were defined, or each object module were compiled with different options. – Clifford Apr 02 '11 at 07:57
  • @Clifford: Oh, sorry, I didn't even see my poorly worded sentence, thanks. And you're actually incorrect there: symbols with the same name (with `inline`) *must* have exactly the same definition, because the compiler *must* treat them as one, or you get undefined behavior. It's not a quality-of-implementation/optimization issue, the language guarantees the linker that `inline`'d functions are exactly the same. – GManNickG Apr 02 '11 at 15:18
  • @GMan: I performed an experiment that does not support either of your your points. Two identical inline functions in the same translation unit were rejected by VC++, Two different inline functions having the same name in separate translation units were accepted - just as if they were `static`. If this were not so, you would not be able to link library code that contained localised inline code that happened to have the same name as one of your own. However the subject is veering off-topic and becoming too complex to discuss in comment blocks where example code is not easily presented. – Clifford Apr 03 '11 at 09:55
  • @Clifford: We seem to be crossing wires. I never said you could define the same function (`inline` or not) in the same translation unit. I did say the same function defined once in multiple translation units must be accepted by the compiler. Please re-read my responses and/or the standard. – GManNickG Apr 03 '11 at 17:25
  • @GMan: Re: "I never said ...", but you did, but you have corrected it in revision 2, so all is good. The post is correct, and my comments regarding multiple definition in a translation unit are void. – Clifford Apr 05 '11 at 10:45
0

The compiler is allowed to ignore the inline keyword. If it's a Very Bad Thing to not inline this, then you should use a #define macro, or make a class with a proper constructor (since you've tagged this as C++), etc.

Matt K
  • 13,370
  • 2
  • 32
  • 51
0

The behavior of the function with regard to variables "allocated on the stack" does not change, regardless of whether it is inlined or not. So, whatever stack-related concerns you have, they are equally valid (or invalid) in either case.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
0

Most compilers only truly inline when optimisation is switched on if at all. Normally you would switch off optimisation for debugging with a source-level debugger and often such debuggers to not behave well with inlined code, making debugging of them more difficult. If the function is implemented normally, the debugger does not need to account for inlining.

Clifford
  • 88,407
  • 13
  • 85
  • 165