问题标签 [offsetof]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - 为非 POD 类型寻找类似于 offsetof() 的东西
我正在寻找一种方法来获取具有非 POD 性质的 C++ 类的数据成员的偏移量。
原因如下:
我想以HDF5格式存储数据,这似乎最适合我的材料(数值模拟输出),但它可能是一个相当面向 C 的库。我想通过 C++ 接口使用它,这需要我像这样声明存储类型(遵循此处和此处的文档(第 4.3.2.1.1 节)):
其中 HOFFSET 是一个使用 offsetof 的特定于 HDF 的宏。
问题当然是,一旦示例类变得更有特色,它就不再是 POD 类型的,因此使用 offsetof 将给出未定义的结果。
我能想到的唯一解决方法是首先将要存储的数据导出到更简单的结构,然后将其传递给 HDF。然而,这确实涉及数据复制,这正是 HDF 试图避免的(以及为什么他们有这个 CompType 使库能够访问您的对象以将其数据保存到文件)。
所以我希望你有更好的想法。理想情况下,我会为这个问题寻找一种可移植的解决方法,但如果没有的话,你可以给我一个可以在 x86 和 x86_64 上使用 GCC 的想法,我已经非常感激了。
----- 稍后附加: -----
Greg Hewgill 在下面建议将数据存储在一个简单的结构中,然后通过继承来构建实际的类。特别是对于 HDF,我认为这实际上可能行不通。比上面更复杂的使用场景:
现在,当我们存储 that_uses_derived_non_pod 类的实例时,我们无法描述它的内存布局,就好像它有一个 base_pod 作为 member_c。这会使偏移量出错,因为 derived_non_pod 添加了一些时髦的东西(我猜是虚拟函数表?)。
c - 为什么这个 offsetof() 的实现有效?
在 ANSI C 中,offsetof 定义如下。
既然我们正在取消引用 NULL 指针,为什么这不会引发分段错误?或者这是某种编译器破解,它看到只有偏移的地址被取出,所以它静态计算地址而不实际取消引用它?这段代码也是可移植的吗?
c++ - 为什么不能在 C++ 中的非 POD 结构上使用 offsetof?
我正在研究如何在 C++ 中获取成员的内存偏移量,并在维基百科上遇到了这个问题:
在 C++ 代码中,您不能使用 offsetof 来访问不是普通旧数据结构的结构或类的成员。
我试过了,它似乎工作正常。
我收到了一些警告,但它已编译并在运行时给出了合理的输出:
我想我要么误解了 POD 数据结构是什么,要么我错过了其他一些难题。我不明白问题是什么。
c - 编译时的偏移量
有没有办法在编译时找到结构成员的偏移量?我希望创建一个包含结构成员偏移量的常量。在下面的代码中,offsetof()
宏在第一printf
条语句中起作用。但是,使用第 10 行声明会ofs
产生错误:
“无法将 '->' 运算符解析为常量表达式”。
还有其他方法吗?
c - 为什么要在 offsetof() 中减去空指针?
Linux 的stddef.h定义offsetof()
为:
而关于offsetof()
(http://en.wikipedia.org/wiki/Offsetof)的维基百科文章将其定义为:
(char *)0
为什么要在维基百科版本中减去?在任何情况下,这实际上会有所作为吗?
c - c struct-embedded union中的成员对齐
我正在修改一些 C 代码,大致如下:
显然,当使用联合的 CharData 成员时,代码会尝试计算结构中感兴趣的字节数。我的问题是,编译器警告联合未命名。所以我把它改成
但是当然我还需要更改最后一行。以下总是会产生与原始结果完全相同的结果吗?
还是有可能,CharData(或 ShortData 或 LongData)不会在联合的开头对齐?
-- 编辑:感谢您的回答。这个问题的答案实际上为我提供了我需要的答案:一个指向联合对象的指针,经过适当转换,指向它的每个成员(或者如果一个成员是位域,则指向它所在的单元),并且反之亦然。.
无论如何,我是否应该为这个问题选择一个答案作为接受的答案?
c - C 中明显的 NULL 指针取消引用实际上是指针算术吗?
我有这段代码。它似乎在这里取消引用空指针,但随后将结果与unsigned int
. 我真的不明白整个部分。它的目的是什么?这是指针算术的一种形式吗?
我得到的输出是 44。但它是如何工作的?
c++ - C++ 类成员变量知道自己的偏移量
是否有可能有一个成员变量,它能够从指向自身的指针(在它的方法中)计算指向包含对象的指针?
让我们在 API 中封装一个外部调用接口,如下所示:
对于从 0 到 N 的其他数量的参数也是如此。对于外部的每个类,一个 C++ 类都声明了一些特征,并且此模板使用这些特征(以及参数类型的更多特征)来查找和调用外部方法。这可以像这样使用:
现在我想做的是以Foo
这样的方式定义,我可以这样称呼:
无需多次重复签名。(显然,创建一个静态成员并将调用包装在一个方法中很简单,对)。好吧,事实上,这仍然很容易:
然而,这意味着对象最终将包含许多指向自身的指针副本。所以我正在寻找一种方法来使这些实例能够计算所有者指针this
和一些额外的模板参数。
我在想
但这抱怨 Foo 在这一点上是不完整的类型。
是的,我知道offsetof
它应该只适用于“POD”类型,但实际上适用于任何非虚拟成员,这将是有效的。我同样尝试在该参数中传递指向(那个)成员的指针(使用虚拟基类),但这也不起作用。
请注意,如果这可行,它还可以用于实现类似 C# 的属性,委托给包含类的方法。
我知道如何使用 boost.preprocessor 执行上述包装方法,但参数列表必须以一种奇怪的形式指定。我知道如何编写宏以通过模板生成通用包装器,但这可能会导致诊断不佳。如果电话看起来像foo.bar()(5)
. 但我想知道一些聪明的技巧是否可能(加上只有这样的聪明技巧可能也可用于属性)。
注意:成员类型实际上不能专门用于指向它的成员指针或偏移量,因为在分配偏移量之前必须知道类型。这是因为类型会影响所需的对齐方式(考虑显式/部分专业化)。
templates - g++ 不允许我将模板参数传递给 offsetof
使用 g++ 时,我将模板参数作为成员变量传递给 offsetof,并收到以下警告:
这是我的用法:
我使用 __builtin_offsetof 得到了同样的错误。有任何想法吗?
谢谢
c++ - 'offsetof' 宏是否从调用未定义的行为?
MSVC 的实现示例:
可以看出,它取消引用一个空指针,这通常会调用未定义的行为。这是规则的例外还是发生了什么?