首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >什么时候使用的函数不会出现在对象文件符号表中?

什么时候使用的函数不会出现在对象文件符号表中?
EN

Stack Overflow用户
提问于 2020-03-28 04:11:46
回答 1查看 401关注 0票数 0

有时,在编译对象文件的符号表(带有nm -aC file.o)中,有些明显被称为函数的转换单元(TU)不存在。可能是什么原因?

原因可能是:

(1)对调用进行了优化:不是针对下面的示例,而是使用-g编译的调试版本。

(2)对调用进行预处理和删除:对于下面的示例来说,在调用周围没有#

(3)别名或预处理后有另一个名称:不是针对下面的示例,而是在AOSP源代码中搜索了skia分支,没有相关的#define/typedef

(4)由于它是内联的,为了提高编译速度,不能在每一个称为它的TU中编译它。

(4-1)但是即使没有编译,它也至少会作为一个未定义的符号出现在对象文件中,稍后由链接器找到,但是下面的示例中根本没有这个符号。

(4-2)如果是这样的话,考虑到调用函数的所有TUs都是独立编译的,编译器如何决定何时编译内联函数?

的其他可能原因是什么?

一个例子是SkOTTable_name.cpp in AOSP10:

代码语言:javascript
复制
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中:

代码语言:javascript
复制
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);
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-03-28 04:57:02

(非显式-专门化)模板实体必须在每个使用实体的翻译单元中有一个定义,以便需要定义。唯一的例外是,如果实体在某个翻译单元中显式实例化。

因此,如果编译器可以内联转换单元中的所有调用(或者没有调用),编译器就不需要发出模板类的成员函数或函数模板的定义,因为编译器知道其他翻译单元也有可用的定义(如果它们需要的话)。如果所有调用都是内联的,也不需要发出未定义的符号,因为没有剩下的调用需要由链接器解决。

上述规则是为什么,如果不使用显式实例化/专门化,通常必须在头文件而不是源文件中定义模板和类模板的成员。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60897142

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档