zoukankan      html  css  js  c++  java
  • C++中模板生成时机

    一、模板
    模板是C++中相对比较不太常见的结构,它实现了一些定义按照使用而动态由编译器实现的功能。或者说它部分实现了一些代码动态生成,将程序员的一些工作转移给了编译器来完成。并且它可以使用和内存的使用一样,只有在真正使用到(需要一种模板定义)的时候,此时才真正生成这种模板的一个实例。这一点和各种现代的内存管理系统一样,模板只是声明,它并不真正进行资源的分配(事实上,如果模板不被引用,它也无法知道如何实例化),只有当真正使用到的时候在进行实体声明。
    二、在何处生成
    模板一般定义于头文件中,例如STL库中的各种基础库模板。然后各个变量引用的时候会进行实例的生成,包括变量、函数、类等的声明。这也就意味着有多少个编译单元使用了一个模板,那么就有多少个编译单元包含了这种类的实例。那么在最终链接的时候是否会出现链接冲突?
    [tsecer@Harry template]$ cat tpl.cpp 
    template <class basetype>
    int nonsense()
    {
        return 0;
    }
    int main()
    {
        return nonsense<char>() + nonsense<int>();
    }
    [tsecer@Harry template]$ g++ -c tpl.cpp 
    [tsecer@Harry template]$ nm tpl.o 
    00000000 _Z8nonsenseIcEiv
    00000000 _Z8nonsenseIiEiv
             U __gxx_personality_v0
    00000000 T main
    [tsecer@Harry template]$ c++filt _Z8nonsenseIcEiv _Z8nonsenseIiEiv
    int nonsense<char>()
    int nonsense<int>()
    [tsecer@Harry template]$ readelf -a tpl.o
    ……
        12: 00000000    33 FUNC    GLOBAL DEFAULT    3 main
        13: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND __gxx_personality_v0
        14: 00000000    10 FUNC    WEAK   DEFAULT    7 _Z8nonsenseIcEiv
        15: 00000000    10 FUNC    WEAK   DEFAULT    8 _Z8nonsenseIiEiv
    也就是模板的实例都是WEAK属性的。之前曾经讨论过每个C++类的虚函数表也是通过WEAK属性实现,所以这里并不是很特别。
    三、命名的一些规则
    上面可以看到其中对于命令的一些规则还是比较诡异的,但是通过gdb的代码是可以看到其中的变量的部分编码方法,其中的_Z是每个C++mangle之后的变量名,之后的8表示了nonsense字符串的长度。
    这一点感觉比较繁琐并且无趣,实现代码位于gdb的gdb-6.0libibertycp-demangle.c文件中,从中可以看到很多的这个变量编码的解析方法。例如其中的模板参数的解析使用
    demangle_template_args
    函数完成,对应的变量_Z8nonsenseIcEiv中从I开始,接下来的c表示模板的参数为一个char类型,E表示模板参数列表开始,i表示返回值为int类型,v表示参数为void类型。

  • 相关阅读:
    csuoj 1355: 地雷清除计划
    Task 6.4 冲刺Two之站立会议3
    Task 10 统计从1到某个整数之间出现的1的次数
    Task 6.3 冲刺Two之站立会议2
    Task 9 从用户界面和体验分析“360极速浏览器”
    Task 6.3 冲刺Two之站立会议1
    《程序员开发心理学》阅读笔记一
    Task 6.2冲刺会议十 /2015-5-23
    Task 6.2冲刺会议九 /2015-5-22
    Task 6.2冲刺会议八 /2015-5-21
  • 原文地址:https://www.cnblogs.com/tsecer/p/10487460.html
Copyright © 2011-2022 走看看