How to define an inline free function (non member function) in C++? - c++

In C++, I need to define some inline general functions.
However, when I write the prototype in a header file and the implementation in a.cpp file, I encounter with "LNK2001 unresolved external symbol" error.
Shall I remove the .cpp file and implement the function in the header file?
I am trying to define some shared non-member math functions that can be used by other classes.
Header file:
inline void foo()
{
//some code
}
.cpp file
//nothing

The name of the inline specifier is somewhat misleading, as it suggests that the function be inlined. However, inline foremost specifies the linkage of the function (it's also a hint to the compiler to consider inlining). For a function declared inline no linkable symbol is generated in the compiled object.
Therefore, inline functions only make sense when defined (not merely declared) in a header file, which is included by, possibly, many compilation units. The inline specifier than prevents multiple (in fact any) symbols for this function to be emitted by the compiler in the respective object files.
If you need a small function only once for one compilation unit, you don't need to declare it anywhere else. Moreover, you don't need to declare it inline, but place it in the anonymous namespace to prevent it from being visible (in the object file generated).
So, either (that's most likely your use case)
// foo.hpp:
inline void foo(bar x) { /* ... */ } // full definition
// application.cpp:
#include "header.hpp"
/* ... */ foo(X);
or
// application.cpp:
namespace {
inline void foo(bar x) // inline specifier redundant
{ /* ... */ }
}
/* ... */ foo(X);

If you want your function to be in-line, you have to provide the definition in the header. If you have it in a separate cpp file it wont be in-lined. The link error is usually due to not including the cpp file during linking stage.

Related

Undefined reference to inlining function with const reference parameters from test case [duplicate]

NB This is not a question about how to use inline functions or how they work, more why they are done the way they are.
The declaration of a class member function does not need to define a function as inline, it is only the actual implementation of the function. For example, in the header file:
struct foo{
void bar(); // no need to define this as inline
}
So why does the inline implementation of a classes function have to be in the header file? Why can't I put the inline function the .cpp file? If I were to try to put the inline definition in the .cpp file I would get an error along the lines of:
error LNK2019: unresolved external symbol
"public: void __thiscall foo::bar(void)"
(?bar#foo##QAEXXZ) referenced in function _main
1>C:\Users\Me\Documents\Visual Studio 2012\Projects\inline\Debug\inline.exe
: fatal error LNK1120: 1 unresolved externals
The definition of an inline function doesn't have to be in a header file but, because of the one definition rule (ODR) for inline functions, an identical definition for the function must exist in every translation unit that uses it.
The easiest way to achieve this is by putting the definition in a header file.
If you want to put the definition of a function in a single source file then you shouldn't declare it inline. A function not declared inline does not mean that the compiler cannot inline the function.
Whether you should declare a function inline or not is usually a choice that you should make based on which version of the one definition rules it makes most sense for you to follow; adding inline and then being restricted by the subsequent constraints makes little sense.
There are two ways to look at it:
Inline functions are defined in the header because, in order to inline a function call, the compiler must be able to see the function body. For a naive compiler to do that, the function body must be in the same translation unit as the call. (A modern compiler can optimize across translation units, and so a function call may be inlined even though the function definition is in a separate translation unit, but these optimizations are expensive, aren't always enabled, and weren't always supported by the compiler)
functions defined in the header must be marked inline because otherwise, every translation unit which includes the header will contain a definition of the function, and the linker will complain about multiple definitions (a violation of the One Definition Rule). The inline keyword suppresses this, allowing multiple translation units to contain (identical) definitions.
The two explanations really boil down to the fact that the inline keyword doesn't exactly do what you'd expect.
A C++ compiler is free to apply the inlining optimization (replace a function call with the body of the called function, saving the call overhead) any time it likes, as long as it doesn't alter the observable behavior of the program.
The inline keyword makes it easier for the compiler to apply this optimization, by allowing the function definition to be visible in multiple translation units, but using the keyword doesn't mean the compiler has to inline the function, and not using the keyword doesn't forbid the compiler from inlining the function.
This is a limit of the C++ compiler. If you put the function in the header, all the cpp files where it can be inlined can see the "source" of your function and the inlining can be done by the compiler. Otherwhise the inlining would have to be done by the linker (each cpp file is compiled in an obj file separately). The problem is that it would be much more difficult to do it in the linker. A similar problem exists with "template" classes/functions. They need to be instantiated by the compiler, because the linker would have problem instantiating (creating a specialized version of) them. Some newer compiler/linker can do a "two pass" compilation/linking where the compiler does a first pass, then the linker does its work and call the compiler to resolve unresolved things (inline/templates...)
The c++ inline keyword is misleading, it doesn't mean "inline this function". If a function is defined as inline, it simply means that it can be defined multiple times as long as all definitions are equal. It's perfectly legal for a function marked inline to be a real function that is called instead of getting code inlined at the point where it's called.
Defining a function in a header file is needed for templates, since e.g. a templated class isn't really a class, it's a template for a class which you can make multiple variations of. In order for the compiler to be able to e.g. make a Foo<int>::bar() function when you use the Foo template to create a Foo class, the actual definition of Foo<T>::bar() must be visible.
The reason is that the compiler has to actually see the definition in order to be able to drop it in in place of the call.
Remember that C and C++ use a very simplistic compilation model, where the compiler always only sees one translation unit at a time. (This fails for export, which is the main reason only one vendor actually implemented it.)
I know this is an old thread but thought I should mention that the extern keyword. I've recently ran into this issue and solved as follows
Helper.h
namespace DX
{
extern inline void ThrowIfFailed(HRESULT hr);
}
Helper.cpp
namespace DX
{
inline void ThrowIfFailed(HRESULT hr)
{
if (FAILED(hr))
{
std::stringstream ss;
ss << "#" << hr;
throw std::exception(ss.str().c_str());
}
}
}
Because the compiler needs to see them in order to inline them. And headers files are the "components" which are commonly included in other translation units.
#include "file.h"
// Ok, now me (the compiler) can see the definition of that inline function.
// So I'm able to replace calls for the actual implementation.
Inline Functions
In C++ a macro is nothing but inline function. SO now macros are under control of compiler.
Important : If we define a function inside class it will become Inline automatically
Code of Inline function is replaced at the place it is called, so it reduce the overhead of calling function.
In some cases Inlining of function can not work, Such as
If static variable used inside inline function.
If function is complicated.
If recursive call of function
If address of function taken implicitely or explicitely
Function defined outside class as below may become inline
inline int AddTwoVar(int x,int y); //This may not become inline
inline int AddTwoVar(int x,int y) { return x + y; } // This becomes inline
Function defined inside class also become inline
// Inline SpeedMeter functions
class SpeedMeter
{
int speed;
public:
int getSpeed() const { return speed; }
void setSpeed(int varSpeed) { speed = varSpeed; }
};
int main()
{
SpeedMeter objSM;
objSM.setSpeed(80);
int speedValue = A.getSpeed();
}
Here both getSpeed and setSpeed functions will become inline

Why is this inline class member function in C++ giving me an unresolved external reference error?

I've been having some problems with declaring functions inline causing unresolved external reference linker errors. I must be misunderstanding something quirky about C++. I'm trying to reduce the compile time of my C++ SDK using a 3-file translation unit where there is one "codeless header" that has only declarations and no implementations, another "code header" that contains all of the templates with implementations, and a unique .cpp filename to minimize hashtable collisions. I'm trying to make either a statically compiled library, DLL, or compile directly into an executable. I want my functions to be inlined, but the problem is that this super basic code will not compile:
// in pch.h
#include <iostream>
#ifdef ASSEMBLE_DYNAMIC_LIB
#ifdef LIB_EXPORT
#define LIB_MEMBER __declspec(dllexport)
#else
#define LIB_MEMBER __declspec(dllimport)
#endif
#else
#define LIB_MEMBER
#endif
// in foo.h
#pragma once
#include "pch.h"
struct LIB_MEMBER Foo {
Foo ();
inline int Bar (); //< inline causes Unresolved external reference error???
};
// in foo.cpp
#include "foo.h"
Foo::Foo () {}
int Foo::Bar()
// main.cpp
#include "foo.h"
int main(int argv, char** args) {
Foo foo;
std::cout << "Hello StackOverflow. foo is " << foo.Bar();
while (1)
;
}
The code results in this linker error:
Severity Code Description Project File Line Suppression State
Error LNK2019 unresolved external symbol "public: int __cdecl
Foo::Bar(void)" (?Bar#Foo##QEAAHXZ) referenced in function
main experiments C:\workspace\kabuki_toolkit\projects\experiments\main.obj 1
All of the code I've found on StackOverflow won't compile with the same error. For example:
// in foo.cpp
#include "foo.h"
Foo::Foo () {}
inline int Foo::Bar() {} //< Again, Unresolved external reference error :-(
The Visual-C++ documetnation has some stuff about how to inline a DLL class member, but they have no code examples.
In C++ inline functions must have their body present in every translation unit from which they are called, otherwise the program is ill-formed. (Ref: C++17 [basic.def.odr]/4)
Marking the class as dllexport or dllimport does not escape that requirement.
NB. The semantics of inline functions in exported classes are described on this MSDN page ; it's exported the same way as a non-inline function; and the importing compiler can choose whether to use the inline definition or the imported definition.
To fix this you could declare Bar as non-inline; or provide the body in the header, e.g.
struct LIB_MEMBER Foo {
Foo ();
void Bar () { }
};
or, equivalently,
struct LIB_MEMBER Foo {
Foo ();
inline void Bar () { }
};
inline void Foo::Bar() {}
As mentioned by the MSDN page, having an exported class with an inline function means that you can't safely change the function in a later release of the DLL without recompiling the client.
You've set ASSEMBLE_DYNAMIC_LIB to NO_0 in the header, which means all of the export flags are ignored. Your pre-processor usage is also wrong: You probably don't want to be using #ifdef, and should be using #if when posing a question...
#if ASSEMBLE_DYNAMIC_LIB == YES_0
If you intend for void Foo::Bar() {} to be inline, then move it to the header file. If it's in the cpp, you'll get an unresolved external error (potentially). It is however worth noting that MSVC will ignore inline in this context, given that you have asked to export the entire class (export overrules inline).
It is possible to export individual member functions as well, if you want to mix & match inline/exported.
class Foo {
public:
LIB_MEMBER Foo ();
OBJ_INLINE void Bar ()
{}
};
Edit: I believe this answer is wrong. Preserved for the comments below.
It is recommended to read the entire documentation page before jumping to coding.
These rules apply to inline functions whose definitions appear within a class definition.
Your function definition does not appear within a class definition, only the declaration does.
foo.cpp won't compile because of the C++ standard (C++14 in this case) Section 9.3 states:
An inline member function (whether static or non-static) may also be defined outside of its class definition provided either its
declaration in the class definition or its definition outside of the
class definition declares the function as inline. [ Note: Member
functions of a class in namespace scope have external linkage. Member
functions of a local class (9.8) have no linkage. See 3.5. —end note ]
There shall be at most one definition of a non-inline member
function in a program; no diagnostic is required. There may be more
than one inline member function definition in a program. See 3.2 and
7.1.2.
Also Section 3.4 also states:
An inline function shall be defined in every translation unit in which
it is odr-used. Exactly one definition of a class is required in a translation unit if the class is used in a way that requires the class
type to be complete.
The keyword to understand here is external linkage; If there is more than one definition of the symbol at link time then it can't be resolved because of the one definition rule1; all C++ class members defined in namespace scope have external linkage and there are multiple definitions of an inline symbol, one for each translation unit, so the external symbol can't be resolved; hence the compile error Unresolved External Symbol. When we put the definition of the declaration outside of the class and mark it inline, it's no different than putting the inline code in the header. So if we move the code from foo.cpp into main.cpp, it works because there is only one TU now and no violates of the one definition rule:
#include "foo.h"
Foo::Foo() {}
inline int
Foo::Bar() { //< No undefined external refrence error.
return 1;
}
int main(int argv, char** args) {
Foo foo;
std::cout << "Hello StackOverflow. foo is " << foo.Bar();
while (1)
;
}
The error in logic of using inline in the declarations for the statically linked library is that we assume that the compiler will not inline the functions automatically using the optimizer. Compilers perform Link-Time Code Generation, or Whole Program Optimisation, where the linker will delay generating the code until link-time and will optimize the intermediate code without the use of a single inline tag2. The problem with using a 3-file translation unit with a DLL is that you're linking at runtime and the intermediate code got deleted so you can't use the Link-time Code Generation to inline the function, so you'll have to put inline functions in the "code header" with the templates.
Updated 9/14/2019 Answer
I have found a significantly more eloquent solution, and you can see an example in the Script2 SDK. The solution is that you only really want one translation unit. I just got 900KB of Script2 code to compile in about 4 seconds total, with 3 seconds spent on pch.cc. The trick is to rename your .cpp files to .inl files, which are inline header files, and include then all in another inline header, Script2 using the module_assembly.inl file. This will prevent you from having to pre-compile a statically linked library and lose the intermediate object code you need for the compiler to auto-inline your functions during the Whole program optimization phase. The new naming convention is that the "codeless header" is a .h file, the "code header" is a .hpp file, and the inline cpp file is .cc.inl file.

Inline functions in multiple translation units

Let's start with the following set of C++ files:
// my_class.h
struct MyClass
{
void my_func();
};
void MyClass::my_func()
{}
// f.h
void f1();
void f2();
// f1.cpp
#include "my_class.h"
void f1()
{
MyClass a;
a.my_func();
}
// f2.cpp
#include "my_class.h"
void f2()
{
MyClass a;
a.my_func();
}
// main.cpp
#include "f.h"
int main()
{
f1();
f2();
return 0;
}
I tried to compile this code with
$ g++ f1.cpp f2.cpp main.cpp
Obviously, the linker complained of duplicate symbol my_func:
duplicate symbol __ZN7MyClass7my_funcEv in:
/var/folders/yj/zz96q16j6vd1dq1_r3mz8hzh0000gn/T/f1-962ae7.o
/var/folders/yj/zz96q16j6vd1dq1_r3mz8hzh0000gn/T/f2-aef78c.o
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
The next attempt I had was to move the function definition inside the class definition, so we get:
struct MyClass
{
void my_func()
{}
};
Running the same g++ command, the program compiles successfully. This is because functions defined in class definition are implicitly marked inline (§10.1.6 * 3).
The standard states:
A function declaration (11.3.5, 12.2.1, 14.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 specified in this section shall still be respected
Which seems somewhat in contradiction to what is written on cppreference.com:
Because the meaning of the keyword inline for functions came to mean "multiple definitions are permitted" rather than "inlining is preferred", [...]
So as far as I understand, having a function defined in the class definition makes it implicitly inline which does not necessarily mean that the compiler will choose to inline its body but will a definition of it in every translation unit. Is this correct?
The second question comes regarding template classes. Separating the declaration/definition of a template class is a problem, as described here so we can only have function definitions in the class definition which makes it implicitly inline, again, right? What is the impact of this?
Since we only have the choice of defining functions in class definitions when the class is a template, what is to be done about classes that are not template? Should we define function in source files and only keep the declaration in headers when possible?
So as far as I understand, having a function defined in the class definition makes it implicitly inline which does not necessarily mean that the compiler will choose to inline its body but will a definition of it in every translation unit. Is this correct?
Correct. When defined inside the class it is marked as inline and it is okay that that defenition is brought into multiple translation units. The compiler will handle that for you.
The second question comes regarding template classes. Separating the declaration/definition of a template class is a problem, as described here so we can only have function definitions in the class definition which makes it implicitly inline, again, right? What is the impact of this?
This is not correct. Templates are special. They aren't actually anything that will exist once the code is compiled. What a template is, is a recipe for stamping out a class or function. As such, they are implicitly inline as well to allow the template to be included in every translation unit that uses it so the compiler can stamp out a concrete class/function from it as needed. This means you can define class member functions outside of the class.
Since we only have the choice of defining functions in class definitions when the class is a template, what is to be done about classes that are not template? Should we define function in source files and only keep the declaration in headers when possible?
Typically you want to put your definitions in a cpp file. The benefit you get from this is you only need to recompile that one cpp file if you change the implementation of the functions. If they were in the header file then you need to recompile every cpp file that includes that header file which leads to longer build times.

Does inline determine internal linkage?

I'm trying to extern an inline function. How I thought it should work:
//a.cpp
inline void f(int) {}
//b.cpp
extern void f(int);
int main() { f(4); }
But getting link error. Then by reading this ("1) It must be declared inline in every translation unit."). What I've tried:
//a.cpp
inline void f(int) {}
//b.cpp
extern inline void f(int);
int main() { f(4); }
Still getting link error. But now, trying something that I don't know what I'm doing:
//a.cpp
extern inline void f(int) {}
//b.cpp
extern inline void f(int);
int main() { f(4); }
It works. What's happening here? Before adding extern to everything, f in a.cpp had internal linkage?
I'm using MSVC 2017 (v141) with /permissive- and /std:c++17
I'm trying to extern an inline function.
There is no reason to use extern with a function. See storage duration - linkage. Functions have external linkage by default; in order to not have external linkage, something special needs to be done (i.e. put it in an anonymous namespace or declare it static). So the normal use of an inline function already exhibits external linkage with no need for the extern keyword.
How I thought it should work:
//a.cpp
inline void f(int) {}
//b.cpp
extern void f(int);
int main() { f(4); }
Then by reading this ("1) It must be declared inline in every translation unit.").
That reference is correct, but look up a bit more where it says "The definition of an inline function [...] must be present in the translation unit where it is accessed [...]." Your example has a declaration of f in b.cpp, but not a definition. If you are going to call f from b.cpp, you need the full definition in that translation unit, as in:
inline void f(int) {}
(This is the same code that exists in a.cpp.) If you leave off the curly braces, then you have a declaration but not a definition, making it illegal to call f from that translation unit.
Basically, it is a real pain to define an inline function outside a header file, unless you give it internal linkage. That's because each source file that uses the inline function would need its own copy of the function body, meaning that if you change the function, you need to make that change in multiple files. Oof. Don't do it. Define each of your inline functions in a header file. If you think you want to define one in a source file, you probably misunderstand what "inline" means.
What does "inline" mean?
As far as the compiler is concerned, the inline keyword means (almost) nothing. It is just a flag on a function definition that gets propagated into the object code so that the linker sees it. The compiler processes the function just as it would any other function. The function may be called normally, or calls to it might be inlined – just like any other function.
The one case where the compiler might do something with the inline flag is when a function is declared inline, is used, but lacks a definition. This is an error that can be caught before the linker takes over. It does not have to be caught by the compiler, but it can be. (If not caught by the compiler, it would be caught by the linker.)
Moving on to the linking stage. When the linker sees the inline flag, it suspends the one-definition rule for that function. The linker will expect to see a definition of the function in each translation unit that still uses the function after the compiler's optimizations. It gets to choose any one of those definitions to serve as the final implementation. Hence the reason that all definitions must match.
And that's about it. The inline keyword basically means that the function definition is in a header file. It tells the linker to not complain when that definition appears in multiple translation units, because that is expected.
Going back to the question, it looks like the intent was to declare an inline function whose definition would appear in only one translation unit. In other words, the function would be flagged as defined in multiple translation units, but the definition would be in only one. Kind of inconsistent there, if not outright contradictory.

c++ emitting inline functions

Let's say that I have a library which contains a public definition of function void foo();. The library calls this function internally. To get the best performance I want internal calls to be inlined. I also want to prevent external code from seeing the definition so that later I can change the implementation without breaking the ABI. Here is a piece of code:
MyLib.h:
void foo();
MyLibInlined.h:
inline void foo() { code here }
MyLib.cpp
#define inline
#include "MyLibInlined.h"
The question is does it break the ODR or is it considered bad practice?
EDIT:
What if foo was a member function?
The question is does it break the ODR or is it considered bad practice?
It doesn't break the ODR, but it breaks the rules in [dcl.fct.spec]:
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.
Instead you should have a public version of the function, which is not declared inline, and have an internal version which you use inside your library:
// MyLibInlined.h
inline void foo_impl() { }
Then inside the library define foo as a call to the internal one:
// MyLib.cpp
#include "MyLibInlined.h"
void foo() { foo_impl(); }
Alternatively, if all the calls to foo() are in a single file you don't need to worry at all, just define it as a non-inline function, and let the compiler inline it in the file where the definition is visible:
// MyLib.h
void foo();
// MyLib.cpp
void foo() { code here }
// use foo ...
The inline keyword doesn't mean the function will be inlined, it means the definition is provided inline in headers. The compiler doesn't need that keyword to be able to inline it within the file where it's defined, because it can see the definition. You only need the inline keyword to allow the definition to appear in multiple translation units without causing a multiple definition error.
AFAIK it does break the ODR, since inline is not so much a rule as it is a guideline. The compiler is allowed to not inline functions despite them being declared so.
On the other hand compilers are also allowed to inline functions that are not declared inline, and are likely to do so for small functions in internal calls (it can do so at link-time in some cases), so just don't worry about it.
Alternatively declare the inline version in a separate namespace and use inline namespaces to resolve it at compile-time (or using or whatever)(http://en.cppreference.com/w/cpp/language/namespace#Inline_namespaces)
It seems to be illegal based on this (C++14 3.2/6)
There can be more than one definition of a [...] inline function with
external linkage [...] in a program provided that each definition
appears in a different translation unit, and provided the definitions satisfy the following requirements. Given
such an entity named D defined in more than one translation unit, then
[...]
— each definition of D shall consist of the same sequence of tokens
Section 3.2 is the section on the one definition rule.
This might be a cleaner variation on what you're doing:
// foo_pub.h -- public interface
#define foo() foo_pub()
void foo_pub();
// foo_private.h -- internal used by library
#define foo() foo_inline()
inline foo_inline() { ... }
// foo_pub.c -- definition for public function
void
foo_pub()
{
foo_inline()
}