Reputation: 125
From my understanding inline functions can go in headers as well as in the source files (with inline keyword) and by default memeber functions defined in headers are tried be inline by the compiler.
My question is with following source files, add.h
#ifndef ADD_H
#define ADD_H
class Add {
public:
int add(int a, int b);
};
#endif /* ADD_H */
add.cpp
#include <iostream>
#include "add.h"
inline int Add::add(int a, int b) {
std::cout << "FUNC: " << __func__ << std::endl;
return a + b;
}
main.cpp
#include "add.h"
int main() {
Add a;
a.add(6,7);
return 0;
}
If i compile the add.cpp and main.cpp
g++ -c add.cpp
g++ -c main.cpp
g++ main.o add.o
It complains about
main.o: In function `main':
main.cpp:(.text+0x1a): undefined reference to `Add::add(int, int)'
collect2: error: ld returned 1 exit status
looking at the symbols in add.o,
U __cxa_atexit
U __dso_handle
000000000000003d t _GLOBAL__sub_I_add.cpp
0000000000000000 t __static_initialization_and_destruction_0(int, int)
U std::ios_base::Init::Init()
U std::ios_base::Init::~Init()
0000000000000000 r std::piecewise_construct
0000000000000000 b std::__ioinit
It doesn't have add function in it which i assume is because the function is inline in .cpp. My question is when we have shared libraries, is it required to define functions inline in headers (add.h in the example) so that source files (main.cpp in the example) using the library gets the functions inlined at obj creation itself? It made no difference when using -flto at linking because function isn't present in the add.o?
Upvotes: 1
Views: 5490
Reputation: 76523
If you define a function in a header file, every source file that #include
s that header gets a copy of that function. You'll get a complaint from the linker that there are duplicate definitions.
If you define a function in a header file and mark it inline
, every source file that #include
s that header gets a copy of that function, but you've told the compiler that that's okay, and the linker won't complain.
If you define a function in a source file and don't mark it inline
it's visible to code in other source files, so they can call that function.
If you define a function in a source file and mark it inline
it's not visible to code in other source files. That's the problem here: Add
is defined in add.cpp
, and it's marked inline
, so it isn't visible to main.cpp
. You can either remove the inline
or move the definition from add.cpp
to add.h
. If you move it to add.h
you can keep it as is and put it after the class definition, or you write it directly inside the class definition and not mark it inline
.
Linker optimization is completely separate from this. Formally, inline
means "expand this function in line if you can", but compilers generally know better than you do what should be done. Linker optimization can expand functions inline, without regard to the inline
keyword and without regard to visibility from other files. But the code has to be correct to begin with, so you have to resolve that missing symbol by fixing the code, not by trying to force some linker optimization.
Upvotes: 8
Reputation: 1243
You could put the function definition inside the header. It's implied to be inline if it's defined inside the class definition.
There's a good answer to this question here
Upvotes: 3