Is "Inline" Implicit in C++ Member Functions Defined in Class Definition

Is inline implicit in C++ member functions defined in class definition

They're equivalent class definitions except for the purposes of the One Definition Rule. So the standard does not guarantee that you can compile one TU (translation unit) with one class definition and a different TU with the other, and then link them together. I doubt that this would ever actually fail on a real implementation, but that's what the standard says.

The inline keyword has approximately nothing to do with inlining. It's about whether multiple identical definitions of the function are permitted in different TUs. If someone moves the function definition elsewhere, then they should decide whether to mark it inline on the following basis:

  • If it is in a .cpp file for that class, then it's valid to mark it inline if it's called only from that TU. Then it probably makes no difference whether it is marked inline or not, but you could mark it inline as a compiler hint if you think the compiler will pay any attention to what you want.

  • If it is still in the header file, then it must be marked inline, or else you'll get multiple definition errors when linking different TUs that use the header.

Assuming that the person moving the function knows those things, I don't think they need a reminder in the class definition. If they don't know those things, then they probably have no business moving the function, but it would be safer for them to have an inline keyword to move with it.

Why are class member functions inlined?

Confusion arises because inline has two effects:

  1. It tells the compiler that the function code can be expanded where the function is called, instead of effectively being called.
  2. It tells the compiler that the function definition can be repeated.

Point 1. is "archaic" in the sense that the compiler can in fact do what it likes in order to optimize code. It will always "inline" machine code if it can and find convenient to do and it will never do that if it cannot.

Point 2. is the actual meaning of the term: if you define (specify the body) a function in the header, since a header can be included in more sources, you must tell the compiler to inform the linker about the definition duplicates, so that they can be merged.

Now, by the language specification, free functions (not defined in class bodies) are by default not defined as inline, so defining in a header a thing like

void myfunc()
{}

if the header is included in more sources, then linked in a same output, the linker will report a multiple definition error, hence the need to define it as

inline void fn()
{}

For class members, the default is the opposite: if you just declare them, they will not be inlined. If you define them, they will be inline.

So a header should look like

//header file

class myclass
{
public:
void fn1()
{} //defined into the class, so inlined by default

void fn2();
};

inline void myclass::fn2()
{} //defined outside the class, so explicit inline is needed

And if myclass::fn2() definition goes into a proper source, must lose the inline keyword.

Is function defined in class always inline?

Functions defined within the class definition are implicitly marked inline.

[C++11: 9.3/2]: A member function may be defined (8.4) in its class definition, in which case it is an inline member function (7.1.2), or it may be defined outside of its class definition if it has already been declared but not defined in its class definition. [..]

That is not the same as saying that they will be inlined.

The inline keyword has implications for storage duration and linkage requirements, and these must be abided by.

[C++11: 7.1.2/2]: A function declaration (8.3.5, 9.3, 11.3) 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.

However, nowadays, your compiler will make the decision on whether to physically inline a function based on its own metrics, not based on the presence or absence of the inline keyword (because, nowadays, frankly the compiler knows best).

I have no idea what "test app" you have in mind, but an example of this in code is very simple:

struct T
{
void foo() {} // implicitly `inline`
};

Why use explicit inline when every class member function is implicitly inlined

If a definition of a member function is within the class body it is implicitly inline. If you only declare it in the class body and you place the definition outside of it you need to make it explicitly inline.

This can be done in two ways:

struct test {
inline void foo();
};

void test::foo() {
}

Or

struct test {
void foo();
};

inline void test::foo() {
}

While both work, the second option is generally recommended.

C++implicity inline function

The only way to guarantee that it is not inline is to make it unreachable at compilation time, for instance, by putting its body definition into cpp file instead of header.

UPDATE: A commenter says that even putting function body into different compilation unit is not guaranteed to help. He is absolutely right. Usually it helps, but some compilers still may inline the function. So, there is no reliable way to disable inlining that is not compiler-dependent.

All the inlining is just a question of optimization. If appropriate optimization is on, by writing an inline keyword you just tell the compiler that you RECOMMEND to inline the function. You can neither force compiler to inline a function, nor force compiler not to inline it. For certain compilers, e.g. VC++, there are ways to do so (__declspec(noinline)), but they all are compiler-dependent.

And why do you need to disable inlining? The compiler often knows better... If it is for debugging purposes, just disable the optimizations, or at least function inlining. You may even use pragmas to do so in a single file. Anyway, debugging a release version should usually be avoided, though sometimes it is impossible to avoid it, of course.

Inline Functions, inside class, C++

all member functions defined inside a class are inlined by default.

No, they are inline by default.

That means that the definition can and must be provided in every translation unit where the functions are used. For member functions that means, where an instance of the class is used.

inline also has a hinting effect about machine code inlining of calls. The compiler can follow or ignore that hint at its discretion, per call.

Is a static member function defined inside a class implicitly inlined?

Yes.

I would quote the standard, but you already did.

considering that I can define the function multiple times in different translation units.

Only if you guarantee that the contents will be the same, making this a non-issue.

Be sure not to conflate "declaration" and "definition" — only when you provide the function body right there inside the class definition does any of this apply. That also makes your worry a non-issue.

// "Is it inline?"      YES.
static void static_f(void) { std::cout << static_data << std::endl; }

// "I guess it isn't" Nope.
static void static_f2(void);

Finally, be aware that these functions will be implicitly marked inline, but this is not the same thing as actually being inlined.

Where does the standard specify that functions defined inside a class are inline?

Perhaps look in the section about, well, inline. /p>

[dcl.inline]/4: A function defined within a class definition is an inline function.

This is actually repeated later, in the section about member functions (which also seems sensible!):

[class.mfct]/1: A member function may be defined in its class definition, in which case it is an inline member function [..]

Are user defined constructors and member functions inline by default?

a. Is the function ClassA(int) inline by default?

b. Is the function GetID(void) inline by default?

Yes. Member functions that are defined within the class definition are implicitly inline.

C++ - avoiding the implicit inlining of a function defined in the class definition

The simple answer is that you should not care. Member functions defined within the class definition are implicitly inline, but that does not mean that they are inlined (i.e. the code need not be inlined at the place of call).

Compiler implementors have dedicated quite a bit of time and resources to come up with heuristics that determine whether actual inlining should be done or not, based on the size of the function, the complexity and whether it can be inlined at all or not (a recursive function cannot be inlined[*]). The compiler has more information on the generated code and the architecture in which it will run than most of us have. Trust it, then if you feel that there might be an issue, profile, and if profiling indicates that you should change the code, do it, but make an informed decision after the fact.

If you want to verify whether the function has actually be inlined or not, you can look at the assembly and check whether there are calls to the function or the code was really inlined.


[*] If the compiler can transform the recursion into iteration, as is the case in tail recursion, then the transformed function could be theoretically be inlined. But then, functions with loops have lesser probabilities of being inlined anyway...



Related Topics



Leave a reply



Submit