Okay, up until now, I thought that functions defined in header files are treated like inline functions, just like template stuff, defined once, and all that.
I also use inclusion guards, yet I still got linker errors of multiple defined objects, and I know that is because of all those different units duplicating stuff the linker tries to pick out which item is the right one.
I also know that inline is merely a suggestion, and might not even get used by the compiler, etc.
Yet I have to explicitly define all those small functions in that little header only toolset I wrote.
Even if the functions were huge, I'd have to declare them inline, and the compiler would still possibly disregard the hint.
Yet I have to define them so anyway.
Example:
#ifndef texture_math_h__
#define texture_math_h__
float TexcoordToPixel(float coord, float dimension)
{
return coord * dimension;
}
float PixelToTexcoord(float pixel, float dimension)
{
return pixel / dimension;
}
float RecalcTexcoord(float coord,float oldDimension, float newDimension)
{
return PixelToTexcoord(TexcoordToPixel(coord,oldDimension),newDimension);
}
#endif // texture_math_h__
Errors are , blabla already defined in xxx.obj, for each unit that includes the file
When I declare all of those inline, it links correctly.
What's the reason for that? It's not a huge problem, and heck, optimizations probably inline stuff found in cpp, too, right?
I'm just curious about the why here, hope it's not too much of a duplicate and thank you for your time.
Inclusion guards only guard against the code being included twice in the same translation unit. So if you have multiple files that include the same header, the code is included multiple times. Functions defined in a header are not inline by default, so this will give you linker errors - you need to define those function with the inline keyword, unless they are member functions of a class.
Also, note that names that contain double-underscores are reserved for the purposes of the C++ implementation - you are not allowed to create such names in your own code.
Member functions are potencially inlined - you can't force inlining! - if (a) they are defined inside the class or if (b) you use the inline-clause in the definition. Note if you are using the inline-clause you shouldn't define the function in the header - the only exception would be templates as these are "special".
As you just updated the question:
Every user of this header will have a definition of the functions -> multiple defintions. You need to separate definition and declaration!
It's all about the one definition rule. This states that you can only have one definition for each non-inline function (along with various other types of entity) in a C++ program across all the translation units that you link in to make the program.
Marking a function inline enables an exception to the usual one definition rule. It states (paraphrased) that you can have one definition of an inline function per translation unit provided that all the definitions match and that a definition is provided in each translation in which the inline function is used.
Include guards will prevent you from accidentally providing more than one definition per translation unit by including the header file containing the definitions multiple times.
To satisfy the one definition rule for a non-inline function you would still have to ensure that there is only one translation unit containing the function definitions. The usualy way to do this is by only declaring the functions in the header file and having a single source file containing the definitions.
Related
So I realize that when including a ".h" file, the compiler essentially copies the contents of that file to the point it was included. So obviously if I had "Utils.h" included in many files, if utils.h holds a functions implementation, it would cause the redefinition error.
I also realize using the inline keyword fixes this problem by essentially eliminating the function and in-lining it at its usage sites.
Now my question is, when the static keyword is used in the header file, it also seems to fix the problem, but I'm not sure I quite understand why/how it fixes the problem...? It's my understanding that static in a cpp file would essentially make it only available in that compilation unit.
To make sure we're all on the same page here is a snippet of the code in question:
//Utils.h (included in many places)
namespace utils {
void someUtil() {
//do work
}
}
where the above would throw the error, but with static and/or inline keyword, there would be no issue.
So I'm wanting to know what static is doing in this case, and should I use that as well as inline if its a small function body or...?
static, tells the compiler to generate the function in every translation unit where it is defined, and just not share it. So you end up with an arbitrary number of technically separate functions existing in the resulting executable if you use in many translation units and if you check the address of the function in different TUs you will have different results.
inline function on the other hand:
There may be more than one definition of an inline function or
variable (since C++17) in the program as long as each definition
appears in a different translation unit and (for non-static inline
functions and variables (since C++17)) all definitions are identical.
For example, an inline function or an inline variable (since C++17)
may be defined in a header file that is #include'd in multiple source
files.
So The compiler will then either inline calls to the function, or merge together the function definitions from different TU's (so that the resulting function exists once in the executable).
so in your case inline is what you need.
I have read existing answers on the two meanings of inline, but I am still confused.
Let's assume we have the following header file:
// myclass.h
#ifndef INCLUDED_MYCLASS
#define INCLUDED_MYCLASS
class MyClass
{
public:
void foo(); // declaration
};
inline void MyClass::foo()
{
// definition
}
#endif
Why does void foo() which is defined outside the class in the file, have to be explicitly defined with inline?
It's because you defined MyClass::foo in a header file. Or a bit more abstract, that definition will be present in multiple translation units (every .cpp file that includes the header).
Having more than one definition of a variable/function in a program is a violation of the one definition rule, which requires that there must be only one definition in a single program of every variable/function.
Note that header guards do not protect against this, as they only protect if you include the same header multiple times in the same file.
Marking the function definition as inline though means that the definition will always be the same across multiple translation units.1.
In practice, this means that the linker will just use the first definition of MyClass::foo and use that everywhere, while ignoring the rest,
1: If this is not the case your program is ill-formed with no diagnostics required whatsoever.
If you put MyClass::foo() in a header file and fail to declare it inline then the compiler will generate a function body for every compilation unit that #includes the header and these will clash at link time. The usual error thrown by the linker is something along the lines of Multiple definition of symbol MyClass::foo() or somesuch. Declaring the function inline avoids this, and the compiler and linker have to be in cahoots about it.
As you mention in your comment, the inline keyword also acts a hint to the compiler that you'd like the function to be actually inlined, because (presumably) you call it often and care more about speed than code size. The compiler is not required to honour this request though, so it might generate one or more function bodies (in different compilation units) which is why the linker has to know that they are actually all the same and that it only needs to keep one of them (any one will do). If it didn't know they were all the same then it wouldn't know what to do, which is why the 'classical' behaviour has always been to throw an error.
Given that the compilers these days often inline small functions anyway, most compilers also have some kind of noinline keyword but that is not part of the standard.
More about inline at cppreference.
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).
Is there any difference between inline member function (function body inline) and other normal member function (function body in a separate .cpp file)?
for example,
class A
{
void member(){}
};
and
// Header file (.hpp)
class B
{
void member();
};
// Implementation file (.cpp)
void B::member(){}
There is absolutely no difference.
The only difference between the two is that the member inside the class is implicitly tagged as inline. But this has no real meaning.
See: inline and good practices
The documentation says that the inline tag is a hint to the compiler (by the developer) that a method should be inlined. All modern compilers ignore this hint and use there own internal heuristic to determine when a method should be inlined (As humans are notoriously bad and making this decision).
The other use of inline is that it tells the linker that it may expect to see multiple definitions of a method. When the function definition is in the header file each compilation unit that gets the header file will have a definition of the function (assuming it is not inlined). Normally this would cause the linker to generate errors. With the inline tag the compiler understands why there are multiple definitions and will remove all but one from the application.
Note on inlining the processes: A method does not need to be in the header file to inlined. Modern compilers have a processes a full application optimization where all functions can be considered for inlining even if they have been compiled in different compilation units. Since the inline flag is generally ignored it make no difference if you put the method in the header or the source file.
Ignore the word inline here and compiler hints because it is not relevant.
The big practical difference in A and B is when they are used in different libraries.
With the case of A you can #include the header and are not required to link against anything. So you can use this class from different applications / libraries without any special linkage.
With the case of B, you need B.cpp and this should be compiled only into one library / application. Any other library or application that needs to use this class will need to link against the one that contains the actual body of the code.
With some setups / implementations you will need to specifically mark the class as "exported" or "imported" between libraries (for example with Windows you can use dllimport / dllexport and with GNU you can use attribute(visibility="default") )
The first one is implicitly inline, i.e. suggesting the compiler to expand it at the call site.
Other than the inline thing, there's a difference in that you could put more definitions in between the definition of class B, and the definition of the function.
For example, B.cpp might include header files that B.hpp doesn't, which can make a significant difference to the build process for large projects.
But even without a separate translation unit, you can occasionally have a circular dependency that's resolved by separating the definitions. For example the function might take a parameter of a type that's forward-declared before B is defined, then defined by the time the function is defined. If that type uses the definition of B in its own definition, it can't just be be defined before B.
I included this header into one of my own: http://codepad.org/lgJ6KM6b
When I compiled I started getting errors like this:
CMakeFiles/bin.dir/SoundProjection.cc.o: In function `Gnuplot::reset_plot()':
/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/include/g++-v4/new:105: multiple definition of `Gnuplot::reset_plot()'
CMakeFiles/bin.dir/main.cc.o:project/gnuplot-cpp/gnuplot_i.hpp:962: first defined here
CMakeFiles/bin.dir/SoundProjection.cc.o: In function `Gnuplot::set_smooth(std::basic_string, std::allocator > const&)':
project/gnuplot-cpp/gnuplot_i.hpp:1041: multiple definition of `Gnuplot::set_smooth(std::basic_string, std::allocator > const&)'
CMakeFiles/bin.dir/main.cc.o:project/gnuplot-cpp/gnuplot_i.hpp:1041: first defined here
CMakeFiles/bin.dir/SoundProjection.cc.o:/usr/include/eigen2/Eigen/src/Core/arch/SSE/PacketMath.h:41: multiple definition of `Gnuplot::m_sGNUPlotFileName'
I know it's hard to see in this mess, but look at where the redefinitions are taking place. They take place in files like /usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/include/g++-v4/new:105. How is the new operator getting information about a gnuplot header? I can't even edit that file. How could that ever even be possible? I'm not even sure how to start debugging this. I hope I've provided enough information. I wasn't able to reproduce this in a small project. I mostly just looking for tips on how to find out why this is happening, and how to track it down.
Thanks.
You're obviously violating the "one definition rule". You have lots of definitions in your header file. Some of them are classes or class templates (which is fine), some of them are inline functions or function templates (which is also fine) and some of them are "normal" functions and static members of non-templates (which is not fine).
class foo; // declaration of foo
class foo { // definition of foo
static int x; // declaration of foo::x
};
int foo::x; // definition of foo::x
void bar(); // declaration
void bar() {} // definition
The one definition rule says that your program shall contain at most one definition of an entity. The exceptions are classes, inline functions, function templates, static members of class templates (I probably forgot something). For those entities multiple definitions may exist as long as no two definitions of the same entity are in the same translation unit. So, including this header file into more than one translation unit leads to multiple definitions.
Looks like you include conflicting headers. Try to check your include paths. They usually are defined in -I directive (at least in gcc) or in an environment variable.
Reading compiler errors usually helps. You should learn to understand what the compiler is telling you. The fact that it is complaining about a symbol being redefine is saying that you are breaking the One Definition Rule. Then it even tells you what the symbols are:
class GnuPlot {
//...
GnuPlot& reset_plot(); // <-- declaration
//...
};
//...
Gnuplot& Gnuplot::reset_plot() { // <-- Definition
nplots = 0;
return *this;
}
You can declare a symbol as many times as you wish within a program, but you can only define it once (unless it is inlined). In this case the reset_plot is compiled and defined in all translation units that include the header, violating the One Definition Rule.
The simplest way out of it is declaring it inline, so that it can appear in more than one compilation unit and let the linker remove the redundant copies (if any) later on.
A little more problematic are the static members that must be declared within the class and defined (only once) in a translation unit. For that you can either create a .cpp file to define those variables (and any function/method that you don't need inlined in the header).