C++程序员应了解的那些事(53)C++中的name mangling

       基本支持函数重载的语言都需要进行name mangling。mangling的目的就是为了给重载的函数不同的签名,以避免调用时的二义性调用。C++程序员需要感谢GNU,GNU BinUtils的工具链用起来实在是太舒服了。

(1)先定义两个简单的函数:

double sum(double x,double y){ 
    return double();
}   
void foo(int lhs,int rhs){
}
g++ -c mangling.cc -o mangling.o
nm -a mangling.o
输出如下(我省略了部分内容):
00000022 T __Z3fooii
00000000 T __Z3sumdd

       被修饰过的名字都以_Z开头,后面数字3是什么意思呢?3是指你的函数名长度。不信你可以换一个函数名试试。对于函数foo而言,ii的含义是你的参数类型的简写,ii代表int int。

(2)可以看一个更复杂的例子,代码引自wiki:

#include <iostream>
namespace wikipedia
{
   class article
   {
   public:
      std::string format (void){
      }
      bool print_to (std::ostream&){
       }
      class wikilink
      {
      public:
         wikilink (std::string const& name){ }
      };
   };
}
这次部分输出如下:
__ZN9wikipedia7article6formatB5cxx11Ev

       可以看出几乎是没有变化的,只不过前面多了该函数所在的命名空间和类。最后会跟一个大写字母E。PS:这个是约定。我个人猜测是End的意思吧。v的意思就很明确了,是指参数为void。5应该是指后面的cxx11。

(3)除了用nm看,还可以用abi::__cxa_demangle函数来实现run-time demangle。这个函数在调试的时候或许会有用,你想看那个函数被调用了。可以写个简单的demo如下:

int main(int argc,char **argv){
  const char *mangling_name="_ZN9wikipedia7article6formatB5cxx11Ev";
  char *demangle_name=(char*)malloc(30);
  int status = 0;
  std::size_t len=30;
  demangle_name=abi::__cxa_demangle(mangling_name,NULL,NULL,&status);
  std::cout<<status<<std::endl;
  if(demangle_name==NULL)
    std::cout<<"demangle failued."<<std::endl;
  std::cout<<demangle_name<<std::endl;
  free(demangle_name);
  return 0;
}

输出如下:

wikipedia::article::format[abi:cxx11]()

注1:我在这里被坑了一次,我直接把上面nm产生的输出(__ZN9wikipedia7article6formatB5cxx11Ev)当作输入。 你把这个当作输入是错的,因为它有两个下划线。实际上应该是一个下划线。你怎么会想到nm产生的符号信息有误!!!!

注2:想接触C++多线程编程,需要从哪方面入手,有没有推荐的书籍或教程?
       多线程编程的难点不在于锁,正常人看一下操作系统再写几个线程demo就可以基本理解了。对于C++而言,甚至连编写线程安全的类也不是难事。只需要用同步原语来保持对共享资源的访问即可。
       我个人觉得最需要的就是实战,写Demo谁都会写。同步原语就那么几个,信号量,互斥量,条件变量等。但是怎么用呢?当你从点击星际争霸到和玩家匹配进行游戏,这当中程序是怎么运行的?事件驱动是怎么驱动的?
       就目前来说,我遇到的困难不是线程的死锁,而是对并发模型的理解。Actor,Reactor模式等。这些东西不实战,个人空想理解起来会吃力。
       我推荐 @陈硕老师的《Linux多线程服务端编程》,我最近在看这本书。这本书给我的观点是实战性很强,而且涉及面也比较广。后几章提到了分布式系统和作者对C++的思考以及STL algotrithm的运用。如作者所说:“对于面向对象,封装式必须的;但继承和多态耦合性太强,很不划算”我就很赞同。同时展示了一个用C++开发的网络库,不过虽然看了这本书,我还是没找到为什么要用C++的理由。我认为C的确可以很好地解决问题。C++的话就RAII算是真的有益处。

       

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值