Consider the following example:
extern void not_defined();
void f() {
not_defined();
}
int main() {}
If I were to compile and link the above program, I get a linker error undefined reference to not_defined(). (https://godbolt.org/z/jPzscK7ja)
This is expected because I am ODR using not_defined.
However, if I make f() a inline function, the program compiles and links correctly (https://godbolt.org/z/qEEob9ann):
extern void not_defined();
// inline is added here
inline void f() {
not_defined();
}
int main() {}
This also works for inline definitions of member functions (since they are also inline?) (https://godbolt.org/z/xce3neofW):
extern void not_defined();
struct C {
void f_member() {
not_defined();
}
void recurse() {
f_member();
};
};
inline void f_free_inline() {
not_defined();
}
// void f_free() {
// not_defined();
// }
int main() {
C c;
// f_free_inline();
}
If I were to uncomment f_free or f_free_inline() in main() it no longer works . This effects seem to be even transitive, since recurse calls f_member, and f_member calls not_defined().
So my questions is, what's special about inline functions that makes this possible?
EDIT:
This trick cease to work if the inline function is inside the purview of a module (even if it is not exported):
export module mod_interface;
extern void not_defined();
export inline void f_module() {
not_defined();
}
The above would result in a linker error for not_defined.
This is sad because I am porting a library to modules and suddenly got a lot of undefined references. Some of those functions in it were wrapped inside inline functions.