在 C 语言中使用类型转换的宏,详细学习偏移量



以下代码及其输出:

#include <stdio.h>
int x = 0;
     #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)x)->MEMBER)
     #define offsetof_1(TYPE, MEMBER) ((size_t) &((TYPE *)1)->MEMBER)
     #define offsetof_2(TYPE, MEMBER) ((size_t) &((TYPE *)2)->MEMBER)
     #define offsetof_3(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
struct test{};
struct m {
     int b;
     char w;
     struct test t;
     int c;
    };
int main(void) {
    printf("Checking:%xn",offsetof(struct m,b));
    printf("Checking:%xn",offsetof_1(struct m,b));
    printf("Checking:%xn",offsetof_2(struct m,b));
    printf("Checking:%xn",offsetof_3(struct m,b));
    return 0;
}
Output:
Checking:0
Checking:1
Checking:2
Checking:0

我正在尝试理解此处使用的类型转换。我认为,编译器的作用是它将(type *)(value)视为从地址(值)开始的类型。因此,对于给定的结构,期望值为 0,即偏移量为 b,但由于我们对类型转换使用了不同的值,因此我们得到了不同的偏移量。如果我的理解正确,请告诉我。我只是想了解文字是如何类型化的及其含义。这在 Linux 内核中使用。因此也标记它们。

offsetof是一个

标准设施。C 标准定义它以某种方式运行,但没有定义编译器如何实现它。大多数编译器依赖于未定义的行为,为了offsetof实现而定义特殊情况。

就语言语义而言,您所做的是无稽之谈。将值2视为指针是未定义行为的典型示例。

用户能够定义自己的offsetof不是语言的设计意图,所以最好不要尝试。

"在引擎盖下",yes指针通常是保存在机器寄存器中的标量,标量算术用于获取结构成员的地址。执行相同的算术来获取对象在"位置零"的地址会在任何对象内产生其通用偏移量。使用零以外的整数作为位置可能会产生算术结果,也可能不会。 (通常会,但这个想法是无稽之谈。

尝试概念上

无意义的程序是发现系统如何工作的一种冒险方式,因为您冒着风险,它会标记错误或在检测到错误后采取快捷方式。

相关内容

  • 没有找到相关文章

最新更新