1

If I declare a large function inline, and the compiler chooses to compile it as a standalone function anyway, is there guaranteed to be only a single copy of that non-inlined inline function in the program, or might the compiler end up creating multiple non-inlined copies of this function in different translation units?

Or, to rephrase that in a way that's almost certain to cause much gnashing of teeth: in cases where preprocessing time is not a concern, is defining a large method inline in a header file an effective way of being able to reuse that code without having to compile/link in a separate translation unit?

iammilind
  • 68,093
  • 33
  • 169
  • 336
Neutrino
  • 8,496
  • 4
  • 57
  • 83
  • `is defining a large method inline in a header file an effective way of being able to reuse that code without having to compile/link in a separate translation unit` I don't think so – Danh Oct 14 '16 at 10:02
  • *"without having to compile/link in a separate translation unit"* What's wrong with that? – Baum mit Augen Oct 14 '16 at 10:02
  • 1
    `inline` is only a hint to compiler, there are no guarantees how it's handled – agg3l Oct 14 '16 at 10:02
  • interesting reading (not duplicate): http://stackoverflow.com/questions/185624/static-variables-in-an-inlined-function – stefaanv Oct 14 '16 at 10:12
  • 1
    Your rephrasing seems not mean the same thing that original question. The program will have at most one definition of the (`inline`) function. But the function might be in several objects (*.o) from TU, but as weak symbol, so linker will *discard* copies when creating executable. – Jarod42 Oct 14 '16 at 10:14
  • @stefaanv That is interesting. From the accepted answer at that link "This has the advantage of "static" (i.e. it can be defined in a header) without its flaws (it exists at most once if it is not inlined)". Which includes correct operation of static variables. – Neutrino Oct 14 '16 at 10:23
  • @Baum It's not that there's anything wrong with that, indeed for a large stand alone body of reusable code it's ideal. But for the case where you wish to access a few helper methods from multiple locations having to link in a separate translation unit for each on it adds work. Less work is generally preferrable to more work. – Neutrino Oct 14 '16 at 10:26
  • 1
    You don't even have a guarantee that there's only one copy of a *non*-`inline` function, not even if the compiler chooses not to inline that function. –  Oct 14 '16 at 10:27

3 Answers3

3

If I declare a large function inline, and the compiler chooses to compile it as a standalone function anyway, is there guaranteed to be only a single copy of that non-inlined inline function in the program,

No. There is no such guarantee. What is guaranteed, is that there will only be a single copy of any static variables declared in the function, and that if you take the address of the function, you will always get the same value.

or might the compiler end up creating multiple non-inlined copies of this function in different translation units?

It might. They might not even be identical: If it can see the argument is always null in one translation unit, it can omit the code for if (arg != nullptr)...`.

3

You need to be extremely specific here, as you are asking for a guarantee. The C++ standard makes guarantees about program behaviour, not about implementation, and even then is not written to protect against malicious compilers. Many implementation details are effectively constrained by behaviour. But not completely.

Compilers are free to embed in your executable 2^17 different copies of any function, inline or not. This would be pointless, but the standard does not ban it! The value and address of static variables would have to be shared, as that is observable, and all the function pointers to each function would have to compare equal if C++ code could get at them (they could have distinct binary representation of the address, just change what it means to do a ==!).

Does this happen? No, but you asked for a guarantee. The C++ standard leaves huge latitude for implementors. Quality of implementation means that modern compilers don't do stupid things that often.

In practice, one inline function is created in each .o file that uses it. It is marked as special ("weak"). When linking statically, all but one of these copies are discarded. Which one is kept will depend on linking order, and can vary from build to build (esp. partial builds). Only one copy of the static locals are kept in a simular way. All pointers to the function or static locals within must compare equal at runtime.

Dynamical linking results in some compilers discarding it when being built into dlls. Other compilers when the .so is loaded look to see if the symbol was already loaded, and if so do not load the copy in the .so. Dynamic linking is the case where it is most likely for multiple copies of the function to continue to exist and be accessed. It this case is not occurring, you are clear, and if it is, test it. C++ standard does not describe dynamic linking.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
0

I would recommend you to go through below question:
"inline" keyword vs "inlining" concept

For optimization purpose, if the inline function is:

  • large enough, then compiler may not do "inlining"
  • short enough, then compiler might do "inlining"

However, in both the cases One Definition Rule (ODR) is guaranteed, since you have used inline keyword.

Community
  • 1
  • 1
iammilind
  • 68,093
  • 33
  • 169
  • 336