注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Tsecer的回音岛

Tsecer的博客

 
 
 

日志

 
 

C++中模板生成时机  

2012-09-09 22:34:26|  分类: 编译器特有相关 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
一、模板
模板是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 W _Z8nonsenseIcEiv
00000000 W _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.0\libiberty\cp-demangle.c文件中,从中可以看到很多的这个变量编码的解析方法。例如其中的模板参数的解析使用
demangle_template_args
函数完成,对应的变量_Z8nonsenseIcEiv中从I开始,接下来的c表示模板的参数为一个char类型,E表示模板参数列表开始,i表示返回值为int类型,v表示参数为void类型。
  评论这张
 
阅读(510)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017