Иногда какая-то явно названная функция в единице перевода (ЕП) отсутствует в таблице символов скомпилированного объектного файла (с помощью nm -aC file.o). Что может быть причиной?
Причина может быть:
(1) Вызов оптимизирован: не для приведенного ниже примера, это отладочная версия, скомпилированная с -g.
(2) Вызов предварительно обрабатывается и удаляется: не для приведенного ниже примера, вокруг вызова нет #if
(3) Он имеет псевдоним или предварительно обработан, чтобы иметь другое имя: не для приведенного ниже примера, выполните поиск в исходном коде AOSP в ветке skia, нет связанного #define/typedef
(4) Поскольку он встроен, для повышения скорости компиляции его нельзя компилировать в каждой TU, которая его вызывает.
(4-1) Но даже если он не скомпилирован, он, по крайней мере, появится в объектном файле как неопределенный символ, который позже будет найден компоновщиком, но в приведенном ниже примере этого символа вообще нет.
(4-2) Если да, учитывая, что все TU, вызывающие функцию, компилируются независимо, как компилятор решает, компилировать встроенную функцию или нет?
Каковы другие возможные причины?
Одним из примеров является SkOTTable_name.cpp в 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));
...
}
Вызванная экземпляр встроенной шаблонной функции "SkTSearch" не является результатом "nm -aC .../SkOTTable_name.o". Кстати, эта функция "SkOTTableName::Iterator::next" (которая вызывает "SkTSearch") находится в таблице символов.
Ссылка:
Вызываемая функция "SkTSearch" находится в 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);
}