9

Edit: I've restored the original title but really what I should have asked was this: 'How do C++ linkers handle class methods which have been defined in multiple object files'

Say I have a C++ class defined in a header along these lines:

class Klass
{
    int Obnoxiously_Large_Method()
    {
        //many thousands of lines of code here
    }
}

If I compile some C++ code which uses 'Obnoxiously_Large_Method' in several locations, will the resulting object file always inline the code for 'Obnoxiously_Large_Method' or will it optimise for size (for example, when using g++ -Os) and create a single instance of 'Obnoxiously_Large_Method' and use it like a normal function?, if so, how do linkers resolve the collisions between other object files which have instantiated the same function?. Is there some arcane C++ namespace Juju which keeps the separate object instances of method from colliding with each other?

NullUserException
  • 83,810
  • 28
  • 209
  • 234
Gearoid Murphy
  • 11,834
  • 17
  • 68
  • 86
  • 5
    Please don't edit a question in this way. It is very confusing, and now all of the answer provided before your edit have no bearing on your edited question. A better approach would be to accept an answer to your original question, and then ask another question. Please edit this question back to the way it was, accpet an answer, and then start a new question. – John Dibling Dec 05 '11 at 22:51

6 Answers6

11

7.1.2 Function specifiers

A function declaration (8.3.5, 9.3, 11.4) with an inline specifier declares an inline function. The inline specifier indicates to the implementation that inline substitution of the function body at the point of call is to be preferred to the usual function call mechanism. An implementation is not required to perform this inline substitution at the point of call; however, even if this inline substitution is omitted, the other rules for inline functions defined by 7.1.2 shall still be respected.

So, the compiler is not required to actually 'inline' any function.

However, the standard also says,

An inline function with external linkage shall have the same address in all translation units.

Member functions normally have external linkage (one exception is when the member function belongs to a 'local' class), so inline functions must have a unique address for cases where the address of the function is taken. In this case, the compiler will arrange for the linker to throw away all but one instance of a non-inlined copy of the function and fix-up all address references to the function to be to the one that's kept.

Michael Burr
  • 333,147
  • 50
  • 533
  • 760
5

Section [9.3], Member functions, of the C++98 Standard states:

A member function may be defined (8.4) in its class definition, in which case it is an inline member function (7.1.2).

Thus, it has always been the case that marking member functions defined in the class definition explicitly inline is unnecessary.

On the inline function specifier, the Standard states:

A function declaration (8.3.5, 9.3, 11.4) with an inline specifier declares an inline function. The inline specifier indicates to the [C++ compiler] that inline substitution of the function body at the point of call is to be preferred to the usual function call mechanism. [However, a C++ compiler] is not required to perform this inline substitution at the point of call;

So, it is up to the compiler whether it will actually inline the definition of the function rather than call it via the usual function call mechanism.

Daniel Trebbien
  • 38,421
  • 18
  • 121
  • 193
4

Nothing is always inlined (unless your compiler has an attribute or private keyword to force it to do so...at which point you're writing $(COMPILER)-flavored C++ rather than standard C++). Very long functions, recursive functions, and a few other things generally aren't inlined.

The compiler can choose not to inline stuff if it determines that doing so will degrade performance, unreasonably increase the object file's size, or make things work incorrectly. Or if it's optimizing for size instead of speed. Or if you ask it not to. Or if it doesn't like your shirt. Or if it's feeling lazy today, cause it compiled too much last night. Or for any other reason. Or for no reason at all.

cHao
  • 84,970
  • 20
  • 145
  • 172
  • But if it is not inlined, there must be an object representation of the method, if so, how are multiple instances of this method across object files resolved by the linker? – Gearoid Murphy Dec 05 '11 at 22:41
  • It has internal linkage; each translation unit effectively gets its own copy. – cHao Dec 05 '11 at 22:43
  • 1
    @GearoidMurphy: Technically, the code is duplicated. But your linker may be smart enough to detect exactly the same code and strip dupes, it is pretty easy to figure out... –  Dec 05 '11 at 22:44
  • @cHao: inline functions can (and do) have external linkage. Vlad is correct, the object code is duplicated, but the code must be specifically noted as duplicated otherwise the linker would give a multiple definitions error. `inline`'s purpose is essentially to suppress the linker error. – deft_code Dec 05 '11 at 23:01
  • §7.1.2.4 *"... An inline function with external linkage shall have the same address in all translation units. ..."*. Not only does this say that inline function have external linkage, but that there must only be one copy of the object code (its address) in the final executable – deft_code Dec 05 '11 at 23:06
  • The example code doesn't include `inline`, though, so that couldn't be part of the keyword's purpose. The compiler would have to note all inlining without regard to whether `inline` was specified or not. As for the rest, i stand corrected. :) – cHao Dec 05 '11 at 23:09
  • More generally, "the compiler can choose not to inline stuff if" it chooses to for any reason, or no reason at all. – Robᵩ Dec 05 '11 at 23:33
2

There is no - single answer to this question. Compilers are smart beasts. You can specifically use the inline words if you want, but this doesn't mean that the compiler will actually inline the function.

Inline is there to help the developer with optmization. It hints at the compiler that something should be inlined, but these hints are generally ignored nowadays, since compilers can do better at register assignment and deciding when to inline functions (in fact, a compiler can either inline or not inline a function at different times). Code generation on modern processors is far more complicated than on the more deterministic ones common when Ritchie was inventing C.

What the word means now, in C++, is that it can have multiple identical definitions, and needs to be defined in every translation unit that uses it. (In other words, you need to make sure it can be inlined.) You can have an inline function in a header with no problems, and member functions defined in a class definition are automatically effectively inline.

That said, I used to work with a greenhills compiler, and it actually obeyed my will more than it disobeyed it :).. It's up to the compiler, really.

FailedDev
  • 26,680
  • 9
  • 53
  • 73
1

It doesn't have to be inlined, no; it's just like if you specified inline explicitly.

When you write inline, you promise that this method won't be called from translation units where it isn't defined, and therefore, that it can have internal linkage (so the linker won't connect one object-file's reference to it to another object-file's definition of it). [This paragraph was wrong. I'm leaving it intact, just struck-out, so that the below comments will still make sense.]

ruakh
  • 175,680
  • 26
  • 273
  • 307
  • Actually, you don't promise anything to the compiler and might still get address of that method or call it from other translation units. –  Dec 05 '11 at 22:43
  • Ah!, so it's like the static keyword, that makes a lot of sense, I hadn't thought of it that way, thanks. – Gearoid Murphy Dec 05 '11 at 22:44
  • @GearoidMurphy: No, it's not. It is just a hint to the compiler to inline the method. It may or may not do so, and most likely will generate non-inlined version if you are trying to take address of such method etc. –  Dec 05 '11 at 22:45
  • Inlining is not what I'm asking about, it's how the compiler handles multiple instances of the same class method across object files, I've updated the question to reflect this. – Gearoid Murphy Dec 05 '11 at 22:49
  • @GearoidMurphy: Copies them! :) –  Dec 05 '11 at 23:09
1

The inline keyword deals with c++ definition of a function. The compiler may inline object code where ever it wants.

Functions defined inline (eg they use the inline keyword), create object code for the function in every compilation unit. Those functions are marked as special so the linker knows to only use one.

See this answer for more specifics.

Community
  • 1
  • 1
deft_code
  • 57,255
  • 29
  • 141
  • 224