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.
Related
//file.h
namespace Foo{
namespace{
void func(){}
}
}
vs
namespace Foo{
void func(){}
}
//file2.cpp use file.h's method
What is the consequence (if there is one) in the calling code (in term of visiblity for example) between this two approach ?
This:
namespace Foo {
namespace {
void func() {}
}
}
Is largely equivalent to this:
namespace Foo {
static void func() {}
}
The difference is that in the static case, the function has internal linkage, so it is not visible to the linker. In the unnamed namespace case, the function has external linkage (is visible to the linker), but under a name which none of your other source files can "normally" access. You might still call the function from a different source file if you reverse-engineer the compiler's name mangling scheme, and the function is still listed among the object file's symbols, for example.
But the common point is that each source file which includes the code (perhaps by #includeing the header file) will contain its own copy of the function. This can have an impact on the size of your binary.
Also, if you need the first one for some reason, you should heavily document it. An unnamed namespace in a header file is generally a "WTF" point, and you do not want these in your code. I must say I can't think of a viable use case for this.
Both variants will allow the function to be found under the name Foo::func().
The compiler might generate different code in the two cases though. Declaring a function inside an anonymous namespace makes that function local to the .cpp file. That is, every .cpp file that includes the header might end up with their own (identical) instantiation of the code for func. This might lead to some bloat in the final executable, due to the duplicated code.
Note that if you define the function inline (as is suggested by your question) this is not really an issue, as the code will be duplicated anyway due to inlining.
Still, as pointed out in the comments: Anonymous namespaces in headers are unusual and will draw the suspicion of however reviews this code. You should always prefer the second option, unless you have very good reason not to.
The first is the equivalent of:
namespace Foo
{
namespace TranslationUnitSpecific
{
void func();
}
}
It means that every time you include the header, you declare
a new, unrelated instance of func. If func is not inline,
you would have to define it in every source file that uses it.
(On the other hand, it does mean that you can provide an
implementation in the header without making the function
inline.)
It also means that you cannot use the function in inline or
template functions defined in a header with risking undefined
behavior, due to violations of the one definition rule.
In general, there are very few, if any cases where you should
use an unnamed namespace in a header.
I have the following class defined in a foo.h header file
class Foo {
public:
inline int Method();
};
inline int Foo::Method() { // Implementation }
I would like now to move the implementation to a foo.cpp file. To this end, I have to remove the inline keyword and move the implementation of the method to a foo.cpp file like this
#include `foo.h`
inline int Foo::Method() { // Implementation }
I have two questions:
Is my statement about the removal of the inline keyword correct? Should it be necessarily removed?
How typically the removal of the inline keyword affect the performance (practically all my methods are inlined)?
Thank you very much in advance.
If you moved the function definition from a header to a cpp file, you MUST remove the inline keyword all all locations for that function. With older linkers it might make things slightly slower, but with modern linkers you should notice no real difference in performance.*
There are certain cases where a public member function can be inline, but that's just a bad idea. Don't do it. Arguments can be made for marking certain private member functions as inline, but in reality what you really want in those to be __attribute__((always_inline)) or __forceinline
*In extremely rare cases it will make a difference, but 99% of the time it won't, and 99.9% of what's left you don't care. If measurements show you hit that one-in-ten-thousand, you can use the aformentioned __forceinline.
Keyword inline is redundant in the class. It is implied if you have a function body.
In the implementation file it is also fairly redundant.
The only use of it is if you define a free function in a header (or a member function outside the class, but in the header) to avoid multiple bodies.
Optimization-wise on mist modern compilers it's even more redundant, they inline anything in sight without question anyway, or ignore your keyword at will.
The inline usage must be consistent! From 7.1.2p4:
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 ] If the definition of a function appears in a translation unit before its first declaration as inline, the program is ill-formed. If a function with external linkage is
declared inline in one translation unit, it shall be declared inline in all translation units in which it appears; no diagnostic is required. ...
You, and the people here giving advice about small functions, are looking at inline the old-fashioned way.
inline used to mean "I want this code to run quickly, so whenever I call this function, I want you to expand it in-place to avoid the overhead of a function call."
That's a really good optimization. It's so good, in fact, that the compiler will eagerly do it even if you don't specify inline.
The compiler is also free to not expand your inline functions. So you really don't have to worry about how it will affect performance, because the compiler can and will ignore inline if you use it in a stupid way.
In fact, compilers today almost always ignore your use of inline, and just do whatever they think is best.
So, knowing that, why do people still use inline?
There's only one reason to use inline nowadays, and that's to work around the One Definition Rule (ODR).
In C/C++, you're only allowed to define a function once. If you do this:
int foo() { /* do something */ }
int foo() { /* do something else */ }
the compiler will complain that you've defined the same function twice.
That looks like a silly example, but it's particularly easy to do something like that when you're using #include - if you defined your function in a header, and you #include the same header twice, this is exactly what you're doing.
Thankfully, inline has another use which is still valid today: if you mark a function as inline, it forces the compiler to silence ODR issues, making it possible to define your function in a header.
In other words, inline now means "I want to define this function in a header."
When you look at it that way, it should be clear that you should remove the inline when moving the function into a cpp file.
For interest sake, there's a couple places where functions are implicitly made inline. One of them is in class member functions:
struct Foo {
void bar() { /* do something */ }
};
I've seen people mark functions like this inline, but that's completely redundant. The compiler does it anyway; there's no need to worry about ODR, and there's no performance to be gained.
The other place is in templates. Since templates have to be defined in headers, they're exempt from the ODR, and inlineing them is redundant.
If the function isn't TINY (or takes several arguments, but doesn't do much, such as a constructor or similar, that takes a bunch of things, and just copies it to somewhere inside the class), inlining it will have little impact on performance in the first place. Setters and getters are usually good candidates to inline, since they (typically) just copy data from one place to another, and can easily be done where the call takes place.
As others have said, it's a "please compiler, if I may ask you kindly, consider inlining this function" - it's not a "make this function inline". The compiler, on the other hand, will often inline functions REGARDLESS of whether there is an inline keyword. It looks at the size of the function, the number of calls and how much larger the code gets from inlining.
If you move the function to "foo.cpp", it will ONLY get inline inside the "foo.cpp" compile unit (typically, compile unit = source file).
That is unless you have a compiler capable of "whole program optimization" or similar tricks, and enable that feature - this basically means that instead of producing a ready to link object file with machine code, the compiler produces a "parsed, but not completely translated to machine instructions" object file. Then, when it comes to finally putting the executable (or shared library) toegether, the compiler/linker will produce one large lump of machine code from the "halfway" code. Both MS and GCC do support this, but I don't know how well it works for large projects.
Edit:
As per Mooing Duck's comment: An inline function doesn't make a real function name in the object file, so the linker may also give errors for unresolved symbol int Foo::Method() [or some wording to that extent].
End edit.
If performance is critical, you should measure the current code's performance, then make your changes, and measure it again. If it's significantly different, you'll have your answer. If it's faster (because of less inlining leading to more cache-hit rate for other bits of code, for example), then that's good. If it's slower, you'll have to put back (some of) the functions into the header file. Or live with it being slower... Or find some other way of making it faster again... The choices are yours (and, if you work in a group, some other people may have a say in the final decision, of course). It's almost impossible for anyone to say for SURE which way it will go without at the very least understanding the whole programs architecture and what goes on in the class - which, given the name "foo.cpp" in the post is probably not the REAL code...
It may be confusing, but you should not think of the purpose of inline to make the compiler inline a function. (Modern compilers are way smarter than you in regards to when a function should be inlined or not anyway).
No, the real purpose of inline is to tell the linker to not worry about multiple definitions of the function. If you put the definition of a (non-member) function in a header, you should mark it inline to avoid linker errors.
2. How typically the removal of the inline keyword affect the performance (practically all my methods are inlined)?
The inline keyword tells the compiler to take the implementation code of that function and put it in place of the function call. This reduces the number of function calls on the stack and if used correctly, can improve the performance of your program.
The inline keyword should only be used with small functions. Get and Set functions are good examples. They set the value of one variable or return the value of one variable.
If you make a function with a lot of code inline, it can increase the size of your code by a lot (depending on the size of the function code and how many times that function is used) and actually DECREASE the performance of your program.
I always try to keep implementation outside of headers, so for templates and inlined functions, I usually do something like this
// File.h
inline bool foo()
#include "File.hpp"
// File.hpp
inline bool foo()
{
return 1;
}
My question is, what does the C++ specification have to say about repeating the inline keyword for the actual implementation of the function? (as shown in this example)
I don't really want to do that as it gets messy with lots and lots of functions, and while my compiler doesn't complain, I wonder if the compiler still accepts the inline hint.
Anyone know?
I tend to put inline as far from the interface as possible since it is an implementation detail and not part of the interface. Hence: omit the first inline in the declaration. And only attach it to the function definition. For the inclusion of an hpp compiler scopes are irrelevant in respect to inline since the files are treated as concatenated.
See also http://www.parashift.com/c++-faq/where-to-put-inline-keyword.html for a more detailed explanation.
It's OK, but putting inline in the source file is even less of a hint, because the sources aren't generally visible to other translation units. If you implement the function outside the header, the compiler will probably not be able to inline it anyways.
The only practical use of inline, in my opinion, is to prevent multiple definition of functions defined in the header.
I'm maintaining a large library of template classes that perform algebraic computations based on either float or double type. Many of the classes have accessor methods (getters and setters) and other functions that run small amounts of code, therefore such functions need to be qualified as inline when the compiler locates their definitions. Other member functions, in contrast, contain sophisticated code and thus would better be called rather than inlined.
A substantial part of the function definitions are located in headers, actually in .inl files included by headers. But there are also many classes whose function definitions happily live in .cpp files by means of explicit instantiation for float and double, which is rather a good thing to do in case of a library (here explained why). And finally, there is a considerable number of classes whose function definitions are broken across .inl files (accessor methods) and .cpp files (constructors, destructors, and heavy computations), which makes them all pretty difficult to maintain.
I would have all my class implementations in .inl files only if I knew a reliable way to prevent some functions from being inlined, or in .cpp files if inline keyword could strongly suggest compiler to inline some of the functions, which, of course, it does not. I would really prefer all the function definitions in the library to reside in .cpp files, but since accessor methods are used extensively throughout the library, I have to make sure they are inlined whenever referenced, not called.
So, in this connection, my questions are:
Does it make any sense to mark the definition of a template function with inline in view of the fact that, as I've recently learnt here, it is going to be automatically qualified as inline by the compiler regardless of whether it's marked with inline or not?
And most importantly, since I would like to have the definitions of all the member functions of a template class gathered together in a single file, either it's .inl or .cpp (using explicit instantiation in case of .cpp), preferably still being able to hint the compiler (MSVC and GCC) which of the functions should be inlined and which shouldn't, sure if such thing is possible with template functions, how can I achieve this or, if there is really no way (I hope there is), what would be the most optimal compromise?
----------
EDIT1: I knew that inline keyword is just a suggestion to the compiler to inline a function.
EDIT2: I really do know. I like making suggestions to the compiler.
EDIT3: I still know. It's not what the question is about.
----------
In view of some new information, there is also third question that goes hand in hand with the second one.
3. If compilers are so smart these days that they can make better choices about which function should be inlined and which should be called and are capable of link-time code generation and link-time optimization, which effectively allows them looking into a .cpp-located function definition at link time to decide its fate about being inlined or called, then maybe a good solution would be simply moving all the definitions into respective .cpp files?
----------
So what's the conclusion?
First of all, I'm grateful to Daniel Trebbien and Jonathan Wakely for their structured and well-founded answers. Upvoted both but had to choose just one. None of the given answers, however, presented an acceptable solution to me, so the chosen answer happened to be the one that helped me slightly more than others in making the final decision, the details of which are explained next for anyone who's interested.
Well, since I've always been valuing the performance of code more than how much convenient it is to maintain and develop, it appears to me that the most acceptable compromise would be to move all the accessor methods and other lightweight member functions of each of the template classes into the .inl file included by the respective header, marking these functions with inline keyword in an attempt to provide the compiler with a good hint (or with a keyword for inline forcing), and move the rest of the functions into the respective .cpp file.
Having all member function definitions located in .cpp files would hinder inlining of lightweight functions while unleashing some problems with link-time optimization, as has been ascertained by Daniel Trebbien for MSVC (in an older stage of development) and by Jonathan Wakely for GCC (in its current stage of development). And having all function definitions located in headers (or .inl files) doesn't outweigh the summary benefit of having the implementation of each class sorted into .inl and .cpp files combined with a bonus side effect of this decision: it would ensure that only the code of primitive accessor methods is visible to a client of the library, while more juicy stuff is hidden in the binaries (ensuring this wasn't a major reason, however, but this plus was obvious for anyone who is familiar with software libraries). And any lightweight member function that doesn't need to be exposed by the include files of the library and is used privately by its class can have its definition in the .cpp file of the class, while its declaration/definition is spiced with inline to encourage the inline status of the function (don't know yet whether the keyword should be in both places or just one in this particular case).
In short: Put the template code in a header file. Use compiler-specific forceinline or noinline keywords if the optimizer fails to make good decisions about inlining.
You can and should put definitions of template members into header files. This ensures that the compiler has access to the definition at the point of use when it finds out what the actual template parameters are, and is able to perform implicit instantiaion.
The inline keyword has very little impact on templates, since template functions are already exempted from the single definition requirement (The One Definition Rule still requires that all definitions be the same). It is a hint to the compiler that the function should be inlined. And you can omit it as a hint to the compiler to not inline the function. So use it that way. But the optimizer will still look at other factors (function size) and make its own choice on inlining.
Some compilers have special keywords, like __attribute__(always_inline) or __declspec(noinline) to override the optimizer's choice.
Mostly, though, the compiler is smart enough not to inline "complex code that makes more sense as a function call". You shouldn't have to worry about it, just let the optimizer do its thing.
Portable inlining control isn't beneficial, because the trade-offs of inlining are very platform-specific. The optimizers should already be aware of those platform-specific tradeoffs, and if you do feel the need to override the compiler's choice, do so on a per-platform basis.
1. Does it make any sense to mark the definition of a template function with inline in view of the fact that, as I've recently learnt, it is going to be automatically qualified as inline by the compiler regardless of whether it's marked with inline or not? Is the behavior compiler-specific?
I think you are referring to the fact that a member function defined in its class definition is always an inline function. This is per the C++ Standard, and has been since the first publication:
9.3 Member functions
...
A member function may be defined (8.4) in its class definition, in which case it is an inline member function (7.1.2)
So, in the following example, template <typename FloatT> my_class<FloatT>::my_function() is always an inline function:
template <typename FloatT>
class my_class
{
public:
void my_function() // `inline` member function
{
//...
}
};
template <>
class my_class<double> // specialization for doubles
{
public:
void my_function() // `inline` member function
{
//...
}
};
However, by moving the definition of my_function() outside of the definition of template <typename FloatT> my_class<FloatT>, it is not automatically an inline function:
template <typename FloatT>
class my_class
{
public:
void my_function();
};
template <typename FloatT>
void my_class<FloatT>::my_function() // non-`inline` member function
{
//...
}
template <>
void my_class<double>::my_function() // non-`inline` member function
{
//...
}
In the latter example, it does make sense (as in, it's not redundant) to use the inline specifier with the definitions:
template <typename FloatT>
inline void my_class<FloatT>::my_function() // `inline` member function
{
//...
}
template <>
inline void my_class<double>::my_function() // `inline` member function
{
//...
}
2. And most importantly, since I would like to have the definitions of all the member functions of a template class gathered together in a single file, either it's .inl or .cpp (using explicit instantiation in case of .cpp), preferably still being able to hint the compiler (MSVC and GCC) which of the functions should be inlined and which shouldn't, sure if such thing is possible with template functions, how can I achieve this or, if there is really no way (I hope there is), what would be the most optimal compromise?
As you know, the compiler may elect to inline a function, whether or not it has the inline specifier; the inline specifier is just a hint.
There is no standard way to force inlining or prevent inlining; however, most C++ compilers support syntactic extensions for accomplishing just that. MSVC supports a __forceinline keyword to force inlining and #pragma auto_inline(off) to prevent it. G++ supports always_inline and noinline attributes for forcing and preventing inlining, respectively. You should refer to your compiler's documentation for details, including how to enable diagnostics when the compiler is unable to inline a function as requested.
If you use those compiler extensions, then you should be able to hint to the compiler whether a function is inlined or not.
In general, I recommend to have all "simple" member function definitions gathered together in a single file (usually the header), by which I mean, if the member function does not require very many more #includes above the set of #includes required to define the classes/templates. Sometimes, for example, a member function definition will require #include <algorithm>, but it is unlikely that the class definition requires <algorithm> to be included in order to be defined. Your compiler is able to skip over function definitions that it does not use, but the larger number of #includes can noticeably lengthen compile times, and it is unlikely that you will want to inline these non-"simple" functions anyway.
3. If compilers are so smart these days that they can make better choices about which function should be inlined and which should be called and are capable of link-time code generation and link-time optimization, which effectively allows them looking into a .cpp-located function definition at link time to decide its fate about being inlined or called, then maybe a good solution would be simply moving all the definitions into respective .cpp files?
If you place all of your function definitions into CPP files, then you will be relying on LTO for mostly all function inlining. This may not be what you want for the following reasons:
At least with MSVC's LTCG, you give up the ability to force inlining (See inline, __inline, __forceinline.)
If the CPP files are linked to a shared library, then programs linking with the shared libraries will not benefit from LTO inlining of library functions. This is because the compiler intermediate language (IL)—the input to LTO—has been discarded and is not available in the DLL or SO.
If Under The Hood: Link-time Code Generation is still correct, "calls to functions in static libraries can't be optimized".
The linker would be performing all inlining, which might be a lot slower than having the compiler perform some inlining at compile time.
The compiler's LTO implementation might have bugs that cause it to not inline certain functions.
Use of LTO might impose certain limitations on projects using your library. For example, according to Under The Hood: Link-time Code Generation, "precompiled headers and LTCG are incompatible". The /LTCG (Link-time Code Generation) MSDN page has other notes, such as "/LTCG is not valid for use with /INCREMENTAL".
If you keep the likely-to-be-inlined function definitions in the header files, then you could use both compiler inlining and LTO. On the other hand, moving all function definitions into CPP files will restrict compiler inlining to only within the translation units.
I don't know where you learnt that, but templates are not "automatically qualified as inline by the compiler regardless of whether it's marked with inline or not". Templates and inline functions both have what is sometimes called "vague linkage" meaning their definitions can be present in multiple objects without error and the linker will use one of the definitions and discard the others. But the fact templates and inline functions both have vague linkage doesn't mean templates are automatically inline. Lions and tigers are both big cats but that doesn't mean lions are tigers.
Unless you know all the instantiations you are using in advance you can't always use explicit instantiation e.g. if you're writing a template library for others to use then you can't provide all the explicit instantiations, so you must define the template in .h (or .inl) files that the user of the code can #include. If you do know all the instantiations in advance then using explicit instantiations in .cpp files has the advantage of improving compilation time, because the compiler only instantiates the templates once in the file containing the explicit instantiations, not in every file that uses them. But that has nothing to do with inlining. For a function to be inlined its definition must be visible to the code calling it, so if you only define function templates (or member functions of class templates) in a .cpp file then they can't be inlined anywhere except in that file. If you define them in a .cpp file and do qualify them as inline then you might cause problems trying to call them from other files, which can't see the inline keyword (if a function is declared inline in one translation unit it must be declared inline in all translation units in which it appears, [dcl.fct.spec]/4.)
For what it's worth, I don't generally bother using .inl files, I just define templates directly in .h files, which gives one less file to deal with. Everything's in one place, and it just works, all files that use the templates can see the definitions and choose to inline them if desired. You can still use explicit instantiations in that case too, to improve compilation time and reduce object file size, without sacrificing inlining opportunites.
Why would that be better than just defining your template code in headers, where it belongs? What exactly are you trying to achieve? If it's fewer files, put the template code in headers, that will always work, the compiler can choose to inline everything without needing LTO, and you only have one file per class template (and you can still use explicit instantiation to improve compilation times). If you're trying to move all your code into .cpp files (which I think you're focusing on too much) then go ahead and do it. I think it's a bad idea, and will probably cause problems (link-time optimisation still has issues with the only compiler I've tried using it with, and certainly won't make compilation any faster) but if that's what you want, do whatever floats your boat.
It seems like your questions revolve around a misunderstanding here:
I would have all my class implementations in .inl files only if I knew a reliable way to prevent some functions from being inlined,
If all your template definitions are in header files you don't need "a reliable way to prevent some functions from being inlined" ... as I said above, templates are not automatially inline just because they're in headers, and if they're too large to inline the compiler won't inline them. First problem solved. Secondly:
or in .cpp files if inline keyword could strongly suggest compiler to inline some of the functions, which, of course, it does not, especially if a function marked with inline is located in a .cpp file.
As I said above, a function marked inline in a .cpp file is ill-formed unless it's also marked inline in the header, and never used in any other .cpp file. So doing this is just making life difficult and possibly causing linker errors. Why bother.
Again, all signs point to just put your template definitions in headers. You can still use explicit instantiation (as GCC does for std::string, as mentioned in the post you link to) so you get the best of both worlds. The only thing it doesn't achieve is hiding the implementations from users of the templates, but it doesn't sound like that's your aim anyway, if it is then provide non-template function API, which can be implemented in terms of templates in a single .cpp file.
This is not a complete answer.
I read that clang and llvm are able to do very comprehensive link time optimization. This includes link time inlining! To enable this, compile with optimization level -O4 when using clang++. The object files will be llvm bytecode instead of machine code. This is what makes this possible. This feature should therefore allow you to put all of your definitions in the cpp files, knowing that they will still be inlined where necessary.
Btw, the length of a function body is not the only thing that determines whether it will be inlined. A lengthy function that is only called from one location can easily be inlined at that location.
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
}