Sometimes some clearly called funtion in a translation unit (TU) is not in the compiled object file's symbol table (with nm -aC file.o). What could be the reason?
The reason could be:
(1) The call is optimized: not for the bellow example, it is the debug version, compiled with -g.
(2) The call is preprocessed and removed: not for the bellow example, there is no #if around the call
(3) It is aliased or preprocessed to have another name: not for the bellow example, have searched in AOSP source code under the skia branch, there is no related #define/typedef
(4) Since it is inlined, to boost compilation speed it may not be compiled in each TU that call it.
(4-1) But even it is not compiled, it will at least appear in the object file as an undefined symbol to be found by the linker later, but there is not that symbol at all in the example bellow.
(4-2) If so, considering all the TUs that call the function are compiled independently, how the compiler decide when to compile the inlined function or not?
What are the other possible reasons?
One example is SkOTTable_name.cpp in AOSP10:
namespace {
bool BCP47FromLanguageIdLess(const BCP47FromLanguageId& a, const BCP47FromLanguageId& b) {
return a.languageID < b.languageID;
}
}
bool SkOTTableName::Iterator::next(SkOTTableName::Iterator::Record& record) {
...
// Handle format 0 languages, translating them into BCP 47.
const BCP47FromLanguageId target = { languageID, "" };
int languageIndex = SkTSearch<BCP47FromLanguageId, BCP47FromLanguageIdLess>(
BCP47FromLanguageID, SK_ARRAY_COUNT(BCP47FromLanguageID), target, sizeof(target));
...
}
The called instantiated templated inlined function "SkTSearch" is not in the result of "nm -aC .../SkOTTable_name.o". BTW that function "SkOTTableName::Iterator::next" (which calls "SkTSearch") is in the symbol table.
Reference:
The called function "SkTSearch" is in SkTSearch.h:
template <typename T, bool (LESS)(const T&, const T&)> struct SkTLessFunctionToFunctorAdaptor {
bool operator()(const T& a, const T& b) { return LESS(a, b); }
};
// Specialization for case when T==K and the caller wants to use a function rather than functor.
template <typename T, bool (LESS)(const T&, const T&)>
int SkTSearch(const T base[], int count, const T& target, size_t elemSize) {
static SkTLessFunctionToFunctorAdaptor<T, LESS> functor;
return SkTSearch(base, count, target, elemSize, functor);
}