Is compiler allowed to ignore inline in case of template specialization? - c++

Lets say you have simple template function (not class member for the sake of simplicity) with type specific specialization in the same .h file...
template <class TYPE>
void some_function(TYPE& val)
{
// some generic implementation
}
template <>
inline void some_function<int>(int& val)
{
// some int specific implementation
}
Unless you explicitly direct you compiler to inline the specialization (inline keyword) you will get linking error if .h file is included more than once (at least I do in Visual C++ 2008).
We all know that inline is just a suggestion to the compiler, which it can ignore. In this particular case is compiler allowed to ignore this suggestion and let linker to fail?

If you don't use inline, then the same function gets compiled with extern linkage into multiple .obj files, which causes the linker to throw a duplicate symbol error.
This is independent of whether the compiler actually compiles your function inline, since it could treat it the same as a static function and make each implementation private to each compilation unit. However, you can't use static for this purpose since it means something else on member functions, so inline is your only choice.

You are misunderstanding the meaning of the often-mentioned "ignore inline" possibility.
No compiler is ever allowed to ignore the inline specifier used in function declaration and the consequences this specifier has with respect to One Definition Rule (ODR).
When someone says that compiler are allowed to "ignore inline", it only means that compilers are not required to actually inline the calls to the function in question. To "ignore inline" means to generate an ordinary (non-inlined) function call to an inline function.
In any case, even if the compiler decided to always generate ordinary calls to an inline function (i.e. to always "ignore inline"), it is still required to treat the function as inline for the purposes of ODR. How the compiler is going to do it is the problem of the compiler. You are not supposed to worry about it.
In your original example you should not not get any linker errors.

This is defined by the standard and the compiler is totally compliant in this regard, from the looks of it. The linkage is all you are after. Implicit template instantiations have 'special' linkage, as inline functions do. There is also static (keyword), which has been deprecated in favor of anonymous namespaces:
namespace {
…declarations…
}
So yes, this specialization (in your example) has the same linkage as:
void some_other_function(int& val) {
// some int specific implementation
}
In fact, the compiler may mumble about inlining the specialization, in your example, saying they do not match. So it really is a best practice to label them both inline (or otherwise).

I believe you can explicitly declare the method as extern and then put the specialization into a .cpp. I've tried something similar in a past life with GCC, but I don't recall the exact details of how it worked. MSDN Magazine has an article on this that might help.

What you're actually seeing is the One Definition Rule (ODR) has a special case for inline functions, in that each TU may have a definition. If the function, such as your explicit int specialization, is not inline, then you will get multiple definition errors at link time. Such inline functions still have external linkage. Function templates are templates and so follow different rules. Instantiations/specializations of a function template are functions.
Using inline, as for any function, is just a hint, but you might want to apply it if the function is short (as for any function) or if you just want to keep it in the header. Here's an example without inline:
Header file:
template<class TYPE>
void some_function(TYPE& val) {
// some generic implementation
}
template<>
void some_function<int>(int& val);
Implementation (.cpp) file:
template<>
void some_function<int>(int& val) {
// some int specific implementation
}

Related

Could a very long Class function member defined in header file?

I defined a class in header file and implemented its function in same header file. I didn't put inline keyword with function definition because I think compiler will regard it as a inline function by default -- but inline is only a hint to compiler, right? What if compiler doesn't regard it as inline function because of its length? I never get error message 'multiple definitions' in reality.
struct tmp {
void print() {
...(very long)
}
};
I didn't put inline keyword with function definition because I think compiler will regard it as a inline function by default
Yes, member functions defined in the body of a class are implicitly inline. The keyword is not necessary.
inline is only a hint to compiler, right? What if compiler doesn't regard it as inline function because of its length?
Yes, sort of. Actually, the inline keyword has two meanings.
The first one is the one you are thinking of, the one that hints to the optimizer to inline the code in the function body at the call site. As you said, this is just a hint—the optimizer is free to ignore this request if it determines that it would be a performance pessimization to do so (or if it is unable to inline for some other technical reason). This meaning of the inline keyword is arguably obsolete. All optimizing compilers nowadays ignore the inline keyword because their authors consider their heuristics to be smarter than the programmer. This is almost always the case, making it rather pointless to try and second-guess the optimizer by marking your functions inline.
The second meaning of the inline keyword is to relax the one-definition rule (ODR), making it legal for there to be multiple definitions of the same function visible to the linker. (Although the behavior of the linker under such circumstances is an implementation detail, most of them will just arbitrarily pick one of the definitions. Which of course only works out well if they are all the same.) This meaning of the inline keyword is still very important, and explains why it is still used today in code.
This is the meaning that your code is benefitting from. Since member functions defined in the body of a class are implicitly marked inline, you do not get multiply-defined symbol errors from the linker.
If you had defined the function in the header file but not within the class definition—in other words, if you had done this:
struct tmp {
void print();
};
void tmp::print()
{ ... }
then you would start getting the multiply-defined symbol errors as soon as that header file was included in two or more compilands (i.e., translation units). This is where you would need to add the inline keyword on the function's definition, not because you want the compiler to "inline" it, but because you want to exempt yourself from the ODR.
EDIT #Leon (below) stated that my answer (reproduced below) was INCORRECT. The correct answer is described here - in short, if the compiler decides to not make a function inline, it still puts it in the object module. But the linker will then pick one of the (potentially many) copies in the different modules and discard all the others.
You are right: you won't get the "multiple definition" error because every time the compiler decides to not put a function inline, it makes the function static within the current module. That means that you could have a large number of copies of your large function littered through your code.

How to call a variadic template helper in anonymous namespace?

In the code below, foo should be a function accessible by anyone, but foo_helper should not, which is why I've put it in an anonymous namespace. Obviously I'm leaving out include guards and includes in this example, but they are there.
foo.h:
namespace
{
void foo_helper() {}
template <typename T, typename... Tail>
void foo_helper(T head, Tail... tail)
{
bar(head);
foo_helper(tail...);
}
}
void foo();
template <typename... Args>
void foo(Args... args)
{
before();
foo_helper(args...);
after();
}
foo.cpp:
void foo() {}
The problem is that in order for foo_helper's variadic template to work, it needs to have that initial version with no argument. But, this forces me to define a non-template function is a header file, which would break after including this file in multiple source files. I cannot move the definition of foo_helper to a source file because it is in an anonymous namespace, since it is not supposed to be accessible.
Is there a way to solve this issue?
inline void foo_helper() {};
solves your problem.
inline mostly means "conflicting definitions of this function are to be discarded, and one of the versions kept".
It also non-bindingly suggests "inlining" in a vague way (in that the standard doesn't really cover what inlining is). Compilers may or may not pay attention to that suggestion.
Note that an anonymous namespace does not "make it unusable" or whatever. Anonymous namespaces are designed to block linker collisions, and that is about it. Create a namespace called details and ... well, trust users not to go and poke inside.
Using an anonymous namespace in a header is a very bad idea.
If there is an inline function (or template function) within another header file that accesses a symbol or function within the anonymous namespace, you are almost certainly going to have an ODR (one definition rule) violation. That is where the same object, function, etc has two definitions that differ, and isn't allowed to.
For example:
inline void bob() {
foo(1,2,3);
}
if that is #included in two different .cpp files, you just made an ill-formed program (no diagnostic required).
Often such ill formed programs "behave the way you expect", but sometimes they do not. As an example, if somewhere along the line you get a static local variable whose existence depends on ODR violation, you can have multiple compilation units disagree asto which one exists and what its properties are.
In a more general sense, the link order of your program could change its behavior, as different definitions are "chosen" (with possibly extremely subtle differences). Or the phase of the moon could do the same.
ODR violations are surprisingly benign, until they byte you with non-local bugs that are hard to track down.
I'll start with an aside: using an anonymous namespace here doesn't serve your purpose. Since you're defining it in a header file, it's not protected at all: it will still be in scope in any file that includes your header. Additionally, since you've defined it in an anonymous namespace, a separate copy of the function will be emitted in each translation unit that uses it, and the linker can't collapse them. If you really want it to be private, I'm not on the up-and-up of the best C++ style these days, so perhaps someone else will correct me, but I would be inclined to use a private namespace:
namespace my_stuff {
void foo_helper();
}
void foo() {
my_stuff::foo_helper();
}
As Yakk indicated, you could use an inline function, and that will allow the compiler to collapse the definitions into one. In modern practice, there shouldn't really be another reason to avoid the inline keyword, because compilers will nowadays decide on their own whether or not to inline functions rather than listening to the hints you give.
Since you have defined the function in an anonymous namespace, as I mentioned above, you actually don't need to do anything else to avoid linker errors if you retain that. The downside to this approach is that you will have separate copies of foo_helper() in each translation unit and those can't be merged by the linker.
There are other gymnastics you could do, mostly involving sizeof..., but I don't think those are ideal.

Is possible to separate declaration and definition of inline functions?

I need to define inline functions to improve performance of my code. At the moment declaration of functions are in .h file and definitions are in .cpp file. I added inline keyword at the front of each declaration of functions but I am getting link error. Is possible to separate declaration and definition of inline functions ?
You can separate the declaration and definition fine, but that definition must be available in every translation unit that uses the function, e.g.:
#include <iostream>
inline void foo();
int main() {
foo();
}
inline void foo() {
std::cout << "Hi\n";
}
is perfectly legal and correct.
The exact quote from n3290 § 7.1.2.4 is:
An inline function shall be defined in every translation unit in which it is odr-used and shall have exactly
the same definition in every case (3.2). [ Note: A call to the inline function may be encountered before its
definition appears in the translation unit. —end note ]
Where § 3.2 basically says that it has to be identical everywhere, even overload resolutions etc.
Are you absolutely sure that making your functions 'inline' would improve your performance? I am pretty sure it will not.
The compiler is able to inline some function calls if and only if it can see the body of the inlined functions. So you need to include the body of the function as well, but if do it, you do not need to annotate your function with 'inline' because the compiler only needs the body of the function -- not your 'inline' keyword. Compilers nowadays are smart and know without your hints whether and when to inline functions. And inlining does not necessarily increase your program's performance, and it is likely to increase your executable's size.
See this article by Herb Sutter. He argues that keyword "inline" has no meaning in C++. But I disagree with him. Keyword "inline" makes one difference: you can specify the body of the inline function more than once in the program (provided that it is exactly the same definition each time) -- this is useful when putting function bodies in headers (if you need this for any reason).
Yes, but you have to put the implementation in the header file. That is because in order to be inlined, the definition has to be known, when including the header.
If you do so, modern compilers will automatically inline the function even without the inline keyword.
Use a separate "implementation header" that you will still include everywhere?
You are need specify only once prototype or realization. Both is eligible.
By definition, inline functions must be known at compile time.
If you want to define them in a separate .h file, you can use a
#pragma once
trick to only insert their definition once.
I have found that in some embedded toolchains, the #inline keyword is not allowed in the function declaration. You can specify it in the definition, but (as stated above) many compilers ignore the keyword anyway.

Inline keyword vs header definition

What's the difference between using the inline keyword before a function and just declaring the whole function in the header?
so...
int whatever() { return 4; }
vs
.h:
inline int whatever();
.cpp:
inline int myClass::whatever()
{
return 4;
}
for that matter, what does this do:
inline int whatever() { return 4; }
There are several facets:
Language
When a function is marked with the inline keyword, then its definition should be available in the TU or the program is ill-formed.
Any function defined right in the class definition is implicitly marked inline.
A function marked inline (implicitly or explicitly) may be defined in several TUs (respecting the ODR), whereas it is not the case for regular functions.
Template functions (not fully specialized) get the same treatment as inline ones.
Compiler behavior
A function marked inline will be emitted as a weak symbol in each object file where it is necessary, this may increase their size (look up template bloat).
Whereas the compiler actually inlines the call (ie, copy/paste the code at the point of use instead of performing a regular function call) is entirely at the compiler's discretion. The presence of the keyword may, or not, influence the decision but it is, at best, a hint.
Linker behavior
Weak symbols are merged together to have a single occurrence in the final library. A good linker could check that the multiple definitions concur but this is not required.
without inline, you will likely end up with multiple exported symbols, if the function is declared at the namespace or global scope (results in linker errors).
however, for a class (as seen in your example), most compilers implicitly declare the method as inline (-fno-default-inline will disable that default on GCC).
if you declare a function as inline, the compiler may expect to see its definition in the translation. therefore, you should reserve it for the times the definition is visible.
at a higher level: a definition in the class declaration is frequently visible to more translations. this can result in better optimization, and it can result in increased compile times.
unless hand optimization and fast compiles are both important, it's unusual to use the keyword in a class declaration these days.
The purpose of inline is to allow a function to be defined in more than one translation unit, which is necessary for some compilers to be able to inline it wherever it's used. It should be used whenever you define a function in a header file, although you can omit it when defining a template, or a function inside a class definition.
Defining it in a header without inline is a very bad idea; if you include the header from more than one translation unit, then you break the One Definition Rule; your code probably won't link, and may exhibit undefined behaviour if it does.
Declaring it in a header with inline but defining it in a source file is also a very bad idea; the definition must be available in any translation unit that uses it, but by defining it in a source file it is only available in one translation unit. If another source file includes the header and tries to call the function, then your program is invalid.
This question explains a lot about inline functions What does __inline__ mean ? (even though it was about inline keyword.)
Basically, it has nothing to do with the header. Declaring the whole function in the header just changes which source file has that the source of the function is in. Inline keyword modifies where the resulting compiled function will be put - in it's own place, so that every call will go there, or in place of every call (better for performance). However compilers sometimes choose which functions or methods to make inline for themselves, and keywords are simply suggestions for the compiler. Even functions which were not specified inline can be chosen by the compiler to become inline, if that gives better performance.
If you are linking multiple objects into an executable, there should normally only be one object that contains the definition of the function. For int whatever() { return 4; } - any translation unit that is used to produce an object will contain a definition (i.e. executable code) for the whatever function. The linker won't know which one to direct callers to. If inline is provided, then the executable code may or may not be inlined at the call sites, but if it's not the linker is allowed to assume that all the definitions are the same, and pick one arbitrarily to direct callers to. If somehow the definitions were not the same, then it's considered YOUR fault and you get undefined behaviour. To use inline, the definition must be known when compiler the call, so your idea of putting an inline declaration in a header and the inline definition in a .cpp file will only work if all the callers happen to be later in that same .cpp file - in general it's broken, and you'd expect the (nominally) inline function's definition to appear in the header that declares it (or for there to be a single definition without prior declaration).

Are free functions implicitly inlined if defined without a previous declaration in C++?

Is the following free function implicitly inlined in C++, similar to how member functions are implicitly inlined if defined in the class definition?
void func() { ... }
Do template functions behave the same way?
It depends what you mean by inlined. A compiler can optimise any function by placing its emitted code inline at the call site. However, if you mean does the code you ask about behave as if it was declared:
inline void func() { ... }
then the answer is no. If you place your code in two different compilation units and build the executable, you will get multiple definition errors. If you explicitly mark the function as "inline", you will not.
Regarding template functions, then some part of the compilation system will see to it that multiple instantiations of the same template do not cause multiple definition errors.
No, it's not implicitly inlined. The compiler has no way of knowing if another module will use this function, so it has to generate code for it.
This means, for instance, that if you define the function like that in a header and include the header twice, you will get linker errors about multiple definitions. Explicit inline fixes that.
Of course, the compiler may still inline the function if it thinks that will be efficient, but it's not the same as an explicit inlining.
Template functions are implicitly inlined in the sense that they don't require an inline to prevent multiple definition errors. I don't think the compiler is forced to inline those either, but I'm not sure.
It might be inlined, depending on if the compiler decides to make it inline or not.