gpt4 book ai didi

c++ - 为什么不能在 C++ 中的非 POD 结构上使用 offsetof?

转载 作者:IT老高 更新时间:2023-10-28 14:01:20 25 4
gpt4 key购买 nike

我正在研究如何在 C++ 中获取类的成员的内存偏移量,并在 wikipedia: 上遇到了这个问题。

In C++ code, you can not use offsetof to access members of structures or classes that are not Plain Old Data Structures.



我试过了,它似乎工作正常。
class Foo
{
private:
int z;
int func() {cout << "this is just filler" << endl; return 0;}

public:
int x;
int y;
Foo* f;

bool returnTrue() { return false; }
};

int main()
{
cout << offsetof(Foo, x) << " " << offsetof(Foo, y) << " " << offsetof(Foo, f);
return 0;
}

我收到了一些警告,但它编译并运行时给出了合理的输出:
Laptop:test alex$ ./test
4 8 12

我想我要么误解了 POD 数据结构是什么,要么我错过了其他一些难题。我不明白有什么问题。

最佳答案

简短回答:offsetof 是仅在 C++ 标准中才有的功能,用于兼容旧的 C。因此,它基本上仅限于可以在 C 中完成的内容。C++ 仅支持 C 兼容性所必须的内容。

由于 offsetof 基本上是一种依赖于支持 C 的简单内存模型的 hack(作为宏实现),因此 C++ 编译器实现者在如何组织类实例布局方面需要很大的自由。

结果是 offsetof 在 C++ 中通常会工作(取决于使用的源代码和编译器),即使在没有标准支持的情况下 - 除非它没有。所以你应该非常小心在 C++ 中使用 offsetof,特别是因为我不知道一个编译器会为非 POD 使用生成警告......现代 GCC 和 Clang 将发出警告如果 offsetof在标准之外使用 ( -Winvalid-offsetof )。

编辑:例如,如您所问,以下内容可能会澄清问题:

#include <iostream>
using namespace std;

struct A { int a; };
struct B : public virtual A { int b; };
struct C : public virtual A { int c; };
struct D : public B, public C { int d; };

#define offset_d(i,f) (long(&(i)->f) - long(i))
#define offset_s(t,f) offset_d((t*)1000, f)

#define dyn(inst,field) {\
cout << "Dynamic offset of " #field " in " #inst ": "; \
cout << offset_d(&i##inst, field) << endl; }

#define stat(type,field) {\
cout << "Static offset of " #field " in " #type ": "; \
cout.flush(); \
cout << offset_s(type, field) << endl; }

int main() {
A iA; B iB; C iC; D iD;
dyn(A, a); dyn(B, a); dyn(C, a); dyn(D, a);
stat(A, a); stat(B, a); stat(C, a); stat(D, a);
return 0;
}

尝试定位字段 a 时会崩溃内型 B静态,当实例可用时它工作。这是因为虚拟继承,其中基类的位置存储在查找表中。

虽然这是一个人为的示例,但实现也可以使用查找表来查找类实例的公共(public)、 protected 和私有(private)部分。或者使查找完全动态(对字段使用哈希表)等。

该标准只是通过将 offsetof 限制为 POD 来保留所有可能性(IOW:无法对 POD 结构使用哈希表...... :)

另一个注意事项:我必须为此示例重新实现 offsetof(此处:offset_s),因为当我为虚拟基类的字段调用 offsetof 时,GCC 实际上会出错。

关于c++ - 为什么不能在 C++ 中的非 POD 结构上使用 offsetof?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1129894/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com