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

发布于 2024-07-15 17:44:24 字数 109 浏览 7 评论 0原文

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

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

Where does Intel C++ Compiler store the vptr ( pointer to virtual function table ) in an Object ?

I believe MSVC puts it at the beginning of the object, gcc at the end. What is it for icpc ( Intel C++ Compiler )?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

﹏雨一样淡蓝的深情 2024-07-22 17:44:24

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

#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

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

You can always look at where this and the first address in the derived class are located:

#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();
}

On my linux box, the result is:

bfdbef3c bfdbef40

...which is exactly what you would expect: the first pointer, plus the size of a virtual function pointer, is the location of the second.

七堇年 2024-07-22 17:44:24

对于Intel 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]);
}

For Intel C++ compiler, for Linux, I found it to be the beginning of the object.

Code:

#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]);
}
醉态萌生 2024-07-22 17:44:24

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

What do you mean "at the beginning of the function"? Anyway, Windows compilers put vptr at the offset 0 of an object, while Unix compiler put it after the last member data. Intel produces compilers for both Windows an Unix, and I would expect that the Win version puts vptr at the beginning, and the *nix version at the end of the object.

森林迷了鹿 2024-07-22 17:44:24

vtable指针在对象中的位置与操作系统无关。 这只是编译器和其他工具的约定。

Sid Datta,你可以从ICC反汇编一些编译模块中发现这些信息。

The position of the vtable pointer in the object is not related to the operating system. It's only a convention of the compiler and other tools.

Sid Datta, you can discover that information from ICC disassembling some compiled module.

神魇的王 2024-07-22 17:44:24

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

Except to satisfy your curiosity the real answer to your question is not going to be very useful, as the C++ standard does not define details like this. Therefore any compiler vendor can implement these features as they see fit.
This is one of the reasons why there is no cross platform ABI (application binary interface) for C++.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文