Your member function x::func1()
is never ODR-used in that compilation unit (source file). Most compilers only generate compiled code for a member function defined inside the class definition if that member function is ODR-used within the compilation unit that is being compiled. Suppose some other source file does use x::func1()
. If you compile that other source file, the compiler will produce object code for x::func1()
in the object file that corresponds to that other source file.
The compiler can get away with bypassing the process of generating compiled code for x::func1()
here because the class definition has to be the same across all compilation units. If you compile some other source file that has a different definition of class x you have violated the one definition rule. This is undefined behavior and no diagnosis is required.
If no source file uses x::func1()
you have some dead code that just never happens to be compiled. The code has an error but it's never detected.
The compiler cannot get away with bypassing generating compiled code for the free function func1()
. This function has external linkage; there's no way the compiler can tell if it might be used somewhere else. The compiler must generate compiled code for that free function.
Here's a minimum working example:
class Missing {
public:
Missing();
int value;
};
class UsesMissing {
public:
int use_missing () {
Missing missing;
return missing.value;
}
int dont_use_missing () {
return 0;
}
};
#ifdef DEFINE_USE_MISSING
int use_missing () {
Missing missing;
return missing.value;
}
#endif
int main () {
UsesMissing test;
#ifdef USE_MISSING
return test.use_missing();
#else
return test.dont_use_missing();
#endif
}
Compile with neither DEFINE_USE_MISSING
or USE_MISSING
defined and this compiles and links just fine with g++ and clang++. Define either one of those flags and the file fails in the link step because of the undefined reference Missing::Missing()
.