Archive for ‘之语言特性’ Category

November 25, 2013

  AT&T 汇编是 GCC 所采用的语法,要点:

  • 寄存器名以 ‘%’ 为前缀:%eax
  • 立即数以 ‘$’ 为前缀:$0x80
  • 指令格式 instrunction src, dest,分别为指令名,源操作数,目的操作数,例如 mov $0, %rax
  • 操作数的宽度以指令名后缀指名,或者由操作数宽度隐式推出:单字节 b,双字节 w,四子节 l,八字节 q。例如 movb $0, (rax)
  • 相对寻址/寄存器寻址/索引寻址均由 seg:off(base, index, scale) 标识。seg 为段寄存器;off 为偏移量;base 为基址寄存器;index 为索引寄存器;scale 为索引的便宜粒度。seg/off/index/scale 均可省略:seg 默认由操作数的属性决定,数据寻址为 ds,代码寻址为 csoff 默认为 0index 默认为 0scale 默认为 1。比如,有个 Message 的结构体数组,该结构体 大小为 16 字节,len 成员的偏移量为 8,数组起始地址保存在 %rbx,元素索引保存在 %rcx,那么,movq 8(rax, rcx, 16), %rdx 将数组的第 %rcx 个元素的 len 成员 load%rdx 中。
Tags: . 1,822 views
November 24, 2013

  上文书介绍了 C++11 中的右值引用及其应用:移动语义和完美转发。本文介绍另外一个应用广泛的特性,变参模板。变参模板允许模板使用个数可变的参数类型来声明模板,包括类模板和函数模板。

Tags: . 1,157 views
November 23, 2013

  C++11 引入的新特性中,除了并发内存模型和相关设施,这些高帅富之外,最引人入胜且接地气的特性就要属『右值引用』了(rvalue reference)。加入右值引用的动机在于效率:减少不必要的资源拷贝。考虑下面的程序:

1
2
std::vector<string> v;
v.push_back("string");

  向 vector 中添加一个元素,这个动作需要先后调用 string::string(const char*), string::string(const string&), string::~string() 三个函数,涉及两次内存拷贝:第一次使用字面常量 “string” 构造出一个临时对象,第二次使用该临时对象构造出 vector 中的一个新元素,『最后临时对象会发生析构』。

Tags: . 3,702 views
June 21, 2013

  分析上述汇编代码。首先获取 guard 变量,判断低字节是否为 0,若非零,表示已经初始化,可以直接使用。否则,将 guard 作为参数调用 __cxa_guard_acquire,如果锁成功,调用 init() 初始化静态变量 foo()::n,然后释放锁。如果锁失败,说明产生竞态条件,则会阻塞当前线程,不同于普通锁的地方在于,__cxa_guard_acquire 是有返回值的(当然 pthread_lock 也有返回值,但用途不同),如果发生了等待,__cxa_guard_acquire 返回 0,并不会进入 foo()::n 的初始化过程(其他线程已经初始化过了,初始化失败的情况就不细究了)。
  为了验证上述分析,可以将 init() 实现成一个耗时的操作,令多个线程“同时”调用 foo(),然后查看各个线程的运行状态。
  对于单线程程序,静态变量的保护是没有必要的,g++ 的 -fno-threadsafe-statics 选项可以禁掉该机制。

Tags: ,. 1,072 views
July 5, 2012

  事情是这样的。我们对tair(淘宝的分布式Key/Value系统)动了一次大手术,更换了网络框架,经过长时间的测试/调试,终于完全通过了回归测试。但要打包发布的时候,却发现服务器可以正常启动,但却完全无法接受请求。调试无果,对比打包前后程序的差异,仅在于是否使用-O2选项对程序进行编译优化。
  无头苍蝇一样,Google搜索“gcc optimization problems”,找到StackOverflow上面的这个帖子,“抱着试试看的心态”,在编译选项中加入-fno-strict-aliasing,bingo!
  -fno-strict-aliasing这个选项是做什么的?aliasing又是什么?C和C++的标准给出了说明:

Strict aliasing is an assumption, made by the C (or C++) compiler, that dereferencing pointers to 
objects of different types will never refer to the same memory location (i.e. alias eachother.)
Tags: ,,. 2,708 views
April 24, 2012

这两个程序的输出均是:

pure virtual method called
terminate called without an active exception
Aborted (core dumped)

原因和父类/子类的构造、析构的顺序,以及vtbl的相应变化有关,有兴趣的同学可以研究下。
注:纯虚函数在纯虚类的vtbl中的对应表项为函数__cxa_pure_virtual(),该函数会调用terminate(),后者打印”pure virtual method called”信息后调用abort自杀。

Tags: . 1,303 views
March 15, 2012

  本菜鸟写了一个server,经长时间激烈的测试以后,终于要在测试环境供外部使用了。经过一天激烈的打包,一枚rpm终于诞生了。上传到公司的yum包仓库,当PE同学部署时遇到了问题。程序在启动过程中莫名地core掉了,屡试不爽。使用gdb查看core文件的程序堆栈,发现程序core在了一个我从来没有修改过的类的析构函数中,core的直接原因就是C/C++程序员的老朋友Segmentation fault同学。查看该析构函数,里面只做了两个操作,简单讲,就是释放对象内存的两个delete。其中一个对象是在类的构造函数中创建,另外一个对象是在其他初始化函数startup中创建。析构函数中理所当然地对这两个对象的指针进行判断,非NULL则delete。这个类很特殊,正常情况下需要调用startup进行初始化,然后作为一个持久的对象使用。也可以不进行初始化,调用其他接口,然后销毁。我使用该类的场景就属于后者。在之前的测试过程中,core dump从未发生。

Tags: . 985 views
November 18, 2011

  我们还知道,类的静态成员函数是不需要绑定到特定对象上面的,所以我们就可以将worker声明为静态成员。

1
2
3
4
5
6
7
8
9
10
11
class Thread
{
public:
    static void* worker(void* args) {
        //~ thread execution.
    }
private:
    //~ here some data member.
};
pthread_t tid;
pthread_create(&tid, NULL, &Thread::worker, NULL);

  我们又知道,静态成岩函数是不能’直接’访问类的非静态成员(包括函数),因此,上面代码中worker即使属于class Thread的类域,但却无法访问这个类的成员,这让人十分不爽。哪位大牛说过来着?任何一个复杂的计算机问题,都可以通过中间层来解决。这里也可以建立一个中间层:使用静态成员函数创建线程,给该函数传递某个对象的地址作为参数,在该静态函数中就可以通过所传递对象的使用它的任何成员了。

Tags: ,. 1,602 views
August 7, 2011

使用变参

  C/C++提供了函数的可变参数(variadic)机制,大部分人写的第一个C程序恐怕就是Hello World吧,使用的应该也是printf(“Hello, World\n”)。printf就是一个使用可变参数的典型,它的原型声明为,

int printf(const char *fmt, ...);

  其中返回值为实际输出字符个数,fmt为格式控制字符串,而”…”便声明了一个可变参数,你可以根据传递0个或多个参数给printf。printf内部会根据格式控制串中的格式指定符号(d, f, p等等)来逐个解析通过可变参数传进的实参变量。
  为解析可变参数,C语言提供了一个va_list类型和四个宏,分别是va_start, va_arg, va_end, 和va_copy,这些宏声明在stdarg.h中。

Tags: ,,. 715 views
May 6, 2011

  关于虚函数,需要知道:

  • 多态在C++中借助虚函数实现
  • 多态只在指针或者引用上发生
  • 虚函数机制(通常)借助虚指针vptr支持
  • 虚函数地址保存在虚函数表中
  • 一个类的所有对象共有一张vtbl
  • vtbl由vptr指向,vptr保存在每一个对象中,多继承时可能有多个vptr
  • vptr由构造函数(普通构造/copy构造)在对象初始化时隐式设定
Tags: ,. 746 views
Page 1 of 1012345678910