英特尔C ++编译器在哪里存储对象中的vptr(指向虚函数表的指针)?

时间:2009-04-01 18:42:39

标签: c++ intel icc

英特尔C ++编译器将对象中的vptr(指向虚函数表的指针)存储在哪里?

我相信MSVC将它放在对象的开头,最后是gcc。什么是icpc(英特尔C ++编译器)?

5 个答案:

答案 0 :(得分:3)

您始终可以查看此类和派生类中的第一个地址所在的位置:

#include <stdio.h>

class foo
{
public:
    virtual int do_foo()=0;
};

class bar : public foo
{
public:
    int bar;
    int do_foo() {printf ("%08x %08x\n", this, &bar);}
};

int main()
{
    bar a_bar;
    a_bar.do_foo();
}

在我的Linux机器上,结果是:

bfdbef3c bfdbef40

...这正是你所期望的:第一个指针加上虚函数指针的大小,是第二个指针的位置。

答案 1 :(得分:1)

对于英特尔C ++编译器,对于Linux,我发现它是对象的开头。

代码:

#include <cstdio>

class A 
{
  int a, b;
public:
  A(int a1, int b1): a(a1), b(b1) {}
  virtual void p(void) { printf("A\n"); }
};

class B: public A
{
public:
  B(int a1, int b1): A(a1, b1) {}
  void p(void){ printf("B\n"); }
};

int main(void)
{
  A a(1, 2); int p=10; A a1(5, 6);
  B b(3, 4); int q=11; B b2(7, 8);

  a.p();
  b.p();

  int * x=(int*)&a;
  printf("%d %d %d %d\n", x[0], x[1], x[2], x[3]);
  x=(int*)&b;
  printf("%d %d %d %d\n", x[0], x[1], x[2], x[3]);
}

答案 2 :(得分:0)

你在“功能开头”是什么意思?无论如何,Windows编译器将vptr放在对象的偏移量0处,而Unix编译器将其放在最后一个成员数据之后。英特尔为Windows和Unix生成编译器,我希望Win版本在开头放置vptr,在对象末尾放置* nix版本。

答案 3 :(得分:0)

对象中vtable指针的位置与操作系统无关。它只是编译器和其他工具的惯例。

Sid Datta,你可以发现ICC的信息反汇编了一些已编译的模块。

答案 4 :(得分:0)

除了满足您的好奇心之外,您问题的真正答案不会非常有用,因为C ++标准没有定义这样的细节。因此,任何编译器供应商都可以根据需要实现这些功能。 这是C ++没有跨平台ABI(应用程序二进制接口)的原因之一。