2012-08-09 99 views
25

我在调试GDB中的一些C++代码,发现有些调用正在使用所谓的“合成指针”。谷歌搜索没有产生任何有意义的结果。在这里搜索,大多数题目中“合成”的问题都涉及到一些Java特性(即使它们暗示“合成”在这种情况下可能意味着“编译器人工产生的东西”)。什么是合成指针?

例如,看这回溯,从一个操作,在MyClass构造进行了,在一个类的成员称为m(此代码已被编译-O2):

#0 MyClass (arg=..., this=<synthetic pointer>) at somefile.h:144 
144  m->lock(); 
gdb$ print this 
$1 = (MyClass * const) <synthetic pointer> 
gdb$ print *this 
$2 = <optimized out> 

上述栈跟踪明确指出this是一个指向已经优化过的对象的指针,但是如何调用一个方法(即它的构造函数)呢?我的猜测是,即使在代码中主动使用了封闭对象(m),一些优化让编译器可以确定封闭对象(this)并非真的必要。由于无法优化的方法调用m->lock()必须放在某处,因此编译器会创建一个位于内存中的“假”(合成?)对象,仅用于包装m

我没有强大的编译器经验,所以我不知道这个结论是否真的有意义。请问有人可以解释一下吗?

谢谢。

回答

12

编译器可以确定this是否实际被解除引用(即使用特定的CPU详细信息,而不是一般的C++规则)。如果某个方法实际上没有取消引用this,则不需要有可用的财务表示。

在评论中,jww提到了另一个案例。一个singleton只有一个副本,所以一个聪明的编译器可以把它的成员当作全局变量。这意味着singleton->foo的地址只是常数&singleton + offset(foo)。作为这种优化的结果,单例方法不需要实际取消引用this以获得对单例成员的访问,因此它可以再次被优化。

+0

是的,我的MyClass对象是构造的,从未被引用过,并在一段时间后被销毁;唯一重要的操作是构造函数/析构函数的副作用(对于记录,它是范围锁的自定义实现)。所以这一定是这样。谢谢。 – 2012-08-09 18:34:58

+2

这是一个合成指针实际上是什么(当“这”被优化了)?我觉得这个答案可以解释为一个附注,即如果从未引用过某个对象可以被优化出来,但并不是说“合成指针”就是“优化”出来的情况。我在堆栈跟踪中看到了合成指针,我不知道如何解释它不是常规的消息。 – 2013-09-18 16:11:04

+2

@JoeyCarson:这一切都有点哲理。形式上,对象既可以存在也可以不存在。优化器运行后,对象可能部分存在,达到可观察行为程序所需的程度。调试器要伪造真实对象,这不是科学。 – MSalters 2013-09-18 19:55:20