gpt4 book ai didi

c - 如何使用 `offsetof` 以符合标准的方式访问字段?

转载 作者:太空狗 更新时间:2023-10-29 16:49:47 28 4
gpt4 key购买 nike

假设我有一个结构并将偏移量提取到一个成员:

struct A {
int x;
};

size_t xoff = offsetof(A, x);

给定一个指向 struct A 的指针,我如何才能以符合标准的方式提取成员?当然假设我们有一个正确的 struct A* 和一个正确的偏移量。一种尝试是做类似的事情:

int getint(struct A* base, size_t off) {
return *(int*)((char*)base + off);
}

这可能会起作用,但请注意,例如,如果指针是同一数组(或末尾的指针)的指针,指针算法似乎只在标准中定义,情况不一定如此。因此从技术上讲,该构造似乎依赖于未定义的行为。

另一种方法是

int getint(struct A* base, size_t off) {
return *(int*)((uintptr_t)base + off);
}

这也可能会起作用,但请注意 intptr_t 不需要存在,据我所知,intptr_t 上的算术不需要产生正确的结果(例如,我记得某些 CPU 具有处理非字节对齐地址的能力,这表明 intptr_t 对数组中的每个 char 以 8 为步长增加)。

看起来标准中遗漏了一些东西(或者我遗漏了一些东西)。

最佳答案

根据 C Standard , 7.19 通用定义 <stddef.h> ,第 3 段,offsetof()定义为:

The macros are

NULL

which expands to an implementation-defined null pointer constant; and

offsetof(*type*, *member-designator*)

which expands to an integer constant expression that has type size_t, the value of which is the offset in bytes, to the structure member (designated by member-designator), from the beginning of its structure (designated by type).

所以,offsetoff()返回以字节为单位的偏移量。

6.2.6.1 总则,第 4 段指出:

Values stored in non-bit-field objects of any other object type consist of n × CHAR_BIT bits, where n is the size of an object of that type, in bytes.

由于 CHAR_BIT 被定义为 char 中的位数, 一个 char是一个字节

因此,根据标准,这是正确的:

int getint(struct A* base, size_t off) {
return *(int*)((char*)base + off);
}

转换 basechar *并添加 off字节到地址。如果offoffsetof(A, x); 的结果, 结果地址是 x 的地址在 structure A 内那base指向。

你的第二个例子:

int getint(struct A* base, size_t off) {
return *(int*)((intptr_t)base + off);
}

取决于添加已签名的 intptr_t 的结果带有无符号 size_t 的值值是无符号的。

关于c - 如何使用 `offsetof` 以符合标准的方式访问字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37412887/

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