As far as I know it's impossible to have a function declared as "inline" in a lib file and have that function "magically inlined" into a caller function into another project (since linking is not the same as compiling and the latter happens before).
How could I inline a function when having multiple functions (into multiple libraries) that have the same declaration but different definition?
e.g.
obj1.lib
void function1() { printf("Hi"); }
obj2.lib
void function1() {printf("whatsup?"); }
main.cpp
void function1();
int main()
{
function1(); // I'd like to be able to inline this, I can steer the linking against obj1 or obj2, but I can't inline this one
}
To inline a function from an object (or a library) file you'll need this object file be compiled with link-time optimization (LTO). See Inlining functions from object files for more details.
Even if you inline functions, they always have to have the same definition: having different defintions for the same entity in a C++ program is a violation of the one definition rule (ODR) specified in 3.2 [basic.def.odr]. ODR violations are often not detected by compilers and linkers and tend to result in rather weird problems.
You'll need to make sure the functions are different, e.g., using one of these techniques:
Give them a different name.
Put the functions into a namespace.
Give the functions a different signature.
Make the static to have them visible only in the given translation units.
The simplest you can do is to give the functions different names.
If you want built-time selection of a function with a given name, that has 2 or more different implementations, and you want to support machine code inlining of that function, then declare it as inline, which requires also supplying the implementation in each variant's header, and use include and lib paths to select the relevant header (for compilation) and lib (for linking) – they'd better match. As with any inline function this doesn't guarantee machine code inlining. With respect to machine code inlining inline is just a hint (it's guaranteed effect is about permitting a definition in each translation unit, and requiring such a definition in each translation unit where it's used).
How to use include and lib paths depends on your toolchain.
Edited in response to Sam Cristall's comment.
If you mean "inline at compile time" then:
In order to use a library you need to include the header file(s) associated with that library. If the desired function is declared inline in that header and the function definition (the body of the function) is available, then the compiler will (at it's discretion) inline the function. Otherwise it won't.
If you mean "inline at link time" (an unfortunate overloading of the word "inline") than see the other answers
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.
This question arose while I was implementing my static library.
I want to check my guess and gain information on using inline functions in static libs.
My guess is that an iplementator of a static lib can not export an inline function in his library
Due to the inline statement is
implemented by a compiler(it is up to the compiler whether to make
the function inline) by placing low level commands representing
operations in the function body to the code segment so that
operations won't be placed in the tables of export/import and
therefore can't be processed by linker and therefore can't be
included by librarian to the code of application to which static lib
is attached. Is my logic right?
I guess that importing function as inline is allowed but I wonder how it is implemented, because it is compiler`s
responsibility but on the linkage state there is only librarian, so
that means that it must undertake some actions in order to make
function inline.
Yes, inline functions are typically placed in a header, so the function body is directly visible to the compiler everywhere the function is used. This lets the compiler evaluate whether to generate inline code for the function in any particular instance.
This basically doesn't arise -- "An inline function shall be defined in every translation unit in which it is odr-used." (§3.2/3). That means if the compiler is going to generate the function inline, what goes into the library is object code that includes inline expansion of the code for that function. Since it's possible that function may not be expanded inline at every use, there will also typically be a definition of the function in the library, but that definition will be used (at least primarily) like a normal function, not expanded inline.
Linkers can also generate code though. Regardless of whether a function is or isn't an inline function by the language standard, and is defined in the same or a different translation unit from the one where it's used, the linker may be able to generate inline code for it anyway.
To make a long story short, the inline keyword has little or no effect on a typical compiler as far as whether a function's code will be generated inline or not. The main (if not sole) effect is that it changes the one-definition rule -- being inline means that multiple (identical) definitions of the same function can exist without causing a problem.
Do you understand the keyword inline - you could equally use replace.
An inline function enables the compile if so choosing to replace the function call with the actual code - nothing to export/import. It is defined in the header file. Anything that uses the object code will require that header code and thus the compiler will replace the function call with the actual code.
On Visual C++ you can use Microsoft specific behavior, and export/import inline functions with __declspec(dllexport) inline or extern inline. Note that this is Microsoft specific behavior, if you target anything but Windows and are not concerned at all with portability, you could consider it.
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 just learned that defining a c++ function inside a class's header file make the function inline. But I know that putting the inline keyword next to a function is only a suggestion and the compiler wont necessarily follow it. Is this the same for header defined c++ functions and is there a difference in behavior between a standalone c++ function and a c++ function that is part of a class?
"defining a c++ function inside a class's header file make the function inline"
That's not true. Defining a function (that is to say, providing the body of the function instead of just a declaration) inside a class definition makes it inline. By "makes it inline", I mean it's the same as giving it the inline keyword. But class definitions don't have to be in headers, and headers can contain other things than class definitions.
So in this example, the function foo is implicitly inline. The function bar is not implicitly inline:
struct Foo {
void foo() {}
void bar();
};
void Foo::bar() {}
"putting the inline keyword next to a function is only a suggestion and the compiler wont necessarily follow it"
inline has two effects. One of them is a hint to the compiler which it can ignore. The other is not optional, and always has its effect. The "hint" is that the compiler is advised to replace calls to that function with a copy of the code for the function itself.
The guaranteed effect is that an inline function can be defined in multiple translation units, and those be linked together, without a multiple definition error, and all but one of the copies is removed by the linker. So, if the example above appears in a header file which is shared between multiple translation units, bar needs to be explicitly marked inline. Otherwise, the linker will discover multiple definitions of bar, which is not allowed.
Despite the name, inline in C++ is mostly about the second, compulsory effect, not the first, optional one. Modern optimising compilers have their own ideas about which calls should be inlined, and don't pay a whole lot of attention to inline when making that decision. For instance I've seen it have an effect in gcc at moderate optimisation levels, but at low levels approximately nothing is inlined, and at high levels approximately everything is (if the definition is available when the call is compiled) unless it makes the function too big.
Whether a function is defined in a header or in a cpp file has absolutely no effect on anything by itself. You can safely imagine that what #include does is copy and paste the header file into the cpp file in the preprocessor, before the compiler ever sees it. If a function is defined in the same translation unit as a call to it, then the function code is available to be inlined by the compiler. If they're in different translation units, then the code is not available and the call can only be inlined by the linker, with whole-program optimisation or similar. A "translation unit" more or less means, "a cpp file, after all the headers have been copy and pasted into it".
C++ compilers are free to choose what will be inline and what won't, no matter what hints you give them. It shouldn't matter if the function is part of a class or not, or whether it is in a header file or source file; the compiler doesn't pay attention to those things while making its decision.
No, not always. The compiler treats it as a hint, just like the inline keyword, but it mostly decides on its own, because it knows better than you what the costs and benefits may be. Inlining the code avoids the function call overhead, but makes the code bigger, which has negative performance impacts on the instruction cache.
These performance hints from the programmer are generally more and more often ignored by the compiler. What it does not ignore (or rather, what the linker does not ignore) is that a function declared inline may appear in several compilation units, and should be treated as multiple copies of the same function without resulting in linker errors.
If you place the definition of a free non-template function in a header file, you will end up with a function definition in each .cpp file that includes the header (directly or indirectly). This can lead to problems when linking.
However, if you declare the function to be inline, the linker will make sure you only use a single definition even if it is included at multiple places.
Consider this:
class Foo{
void func1(){
/*func1 code*/
}
void func2(){
/*func2 code*/
}
};
Case 1: class Foo in Foo.h
Case 2: class Foo nicely seperated among Foo.h and Foo.cpp
Various other cpp files include Foo.h
My question is...Will Case 1 lead to a bigger binary?
Maybe it will, maybe it won't. It really has nothing to do with header files. What matters here is that your member functions are defined in the class definition. When member functions are defined like that, they are treated as inline functions. If the compiler decides not to actually inline any calls to these functions, there won't be any impact on code size. If the compiler decides to inline any (or all) of the calls, the answer would be "it depends". Inlining calls to small functions might result in increased code size as well as in decreased code size. This all depends on the function itself and on the compiler's capabilities (optimization capabilities specifically).
If compiler decides not to inline those functions, and generate separate body for them, these bodies will appear in each object file who uses them, but with special flag for linker - 'weak symbol'. When linker finds this flag, it will combine all symbols with that name into only one resulting symbol (maybe it will produce error message if bodies or sizes of such symbols are different)
Also RTTI info and vtables also use same scenario.
With dynamic libraries, weak symbol joining may happen at run-time, if they uses the same class.
If the functions in the header are declared as static, than yes, each module (source file) that includes that header file will store a copy of that function in the object file and the final executable will be bigger in size...
If you have the code definition in the header, the compiler might create redundant copies of each function whenever you include the .h. Those redundant copies might also trigger errors from the linker, so the practice is generally frowned upon except for inline functions.
If the code for functions is included inline in the headers, then the compiler can use that to define the functions in the object code for each separate source file, or embed the function code directly where the functions are called. Depending on your compiler and linker and the support for C++ generally, that may leave you with larger code than you would have with the functions all defined separately. If the inline functions are small enough, you may save space by avoiding function call overhead. However, such functions have to be very small.