`
freesoftman
  • 浏览: 319817 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

再次理解offsetof的实现原理

阅读更多

offsetof的原型为:

size_t offsetof(type, member);

 

DESCRIPTION
       The  macro  offsetof()  returns the offset of the field member from the
       start of the structure type.

       This macro is useful because the sizes of the  fields  that  compose  a
       structure  can  vary  across  implementations, and compilers may insert
       different numbers of padding bytes between  fields.   Consequently,  an
       element's  offset  is  not necessarily given by the sum of the sizes of
       the previous elements.

       A compiler error will result if member is not aligned to a byte  bound‐
       ary (i.e., it is a bit field).

RETURN VALUE
       offsetof()  returns  the  offset  of  the given member within the given
       type, in units of bytes.

CONFORMING TO
       C89, C99, POSIX.1-2001.

 

以上内容摘自开发文档。

 

大意就是获取结构体成员member在结构体type中的偏移量。

 

其实offsetof就是一个宏定义,我们也可以自己实现的。接下来就来分析这个宏的具体实现。

struct type{

    int a;

    int b;

    int member;

    int c : 1;

}

 

#define offsetof(type, member)   (size_t)&(((type *)0)->member)

 

type是一个结构体,定义如上所示,它有一个member成员,返回的是结构体type的成员member相对type的偏移地址。

 

这里的一个妙处就:(type *)0骗编译器说有一个指向结构体type的指针,地址值是0。

然后在取该指针的member地址 &((type *)0)->member,因为基址是0,所以这时member的地址就是member在type中的偏移量了。

 

最后转换成size_t型,即unsigned int。

分享到:
评论

相关推荐

    Linux内核中链表和散列表的实现原理揭秘

    ### Linux内核中链表和散列表的实现原理揭秘 #### 一、引言 Linux内核作为操作系统的核心部分,在其内部实现上广泛采用了多种高效的...深入理解这些数据结构的实现原理,对于进一步学习和开发Linux内核具有重要意义。

    memoffset:Rust的offsetof

    备忘录集 类似于Rust结构的offset_of功能。 引入以下宏: offset_of! 用于获取结构成员的偏移量。 offset_of_tuple! 用于获取元组成员的偏移量。 (需要Rust 1.20+) ... 用于获取一个或多个字段跨度的范围。...

    结构体中的偏移1

    `offsetof`宏的一个常见应用是在实现通用数据结构时,例如Linux内核中使用的`container_of`宏,它允许从嵌套元素的指针反向找到包含它的结构体。`container_of`宏的定义如下: ```c #define container_of(ptr, type...

    C++ 内存管理算法和实现

    《C++ 内存管理算法和实现》是一本深入探讨C++内存管理的权威著作,对于程序员来说,理解和掌握内存管理是提升编程技能的关键。内存管理不仅涉及到程序的效率,也直接影响到程序的稳定性和安全性。本文将围绕该书的...

    用C++实现反射的例子

    总的来说,C++的反射实现通常需要深入理解模板元编程和宏预处理器的使用。尽管这在某些情况下可能不是最佳实践,但这种技术可以扩展C++的静态类型系统的功能,使代码更加灵活。对于那些需要在运行时动态操作对象属性...

    LW-OOPC宏配置及使用指南

    如果开发环境中连自定义的offsetof宏都不支持,可能会影响到多态特性的实现。此外,可以通过定义`LW_OOPC_SUPPORT_MEMORY_LEAK_DETECTOR`来开启内存泄漏检测功能。 LW-OOPC的主要宏有以下三个: 1. **INTERFACE**...

    C标准库源代码

    源代码能帮助我们理解字符串操作的底层原理。 4. **数学运算**:`<math.h>`提供了各种数学函数,如平方根`sqrt()`、指数`exp()`、三角函数等。通过源代码,我们可以看到这些复杂数学运算的实现。 5. **时间管理**...

    NTFS-3G内部结构(具体文档分析)

    本文档将深入探讨NTFS-3G的内部结构,以便于开发者理解其工作原理和进行相应的开发或维护。 首先,NTFS-3G的源代码结构包括多个关键组件。`version.h`包含了NTFS库的版本信息,`ntfs_libntfs_version()`函数则用于...

    获取类成员在类中的位移及大小

    总结一下,理解和利用`offsetof`宏获取类成员的位移以及`sizeof`运算符获取成员的大小,是C++程序员掌握的一种高级技能。这不仅简化了大量属性设置的代码,也有助于代码的维护和扩展。然而,需要注意的是,这些操作...

    轻量级的面向对象C语言编程框架介绍.doc

    LW_OOPC 是一个专为C语言设计的轻量级面向对象编程框架,它通过宏定义实现了C语言中的面向对象特性,如继承、多态等。...通过理解和熟练使用LW_OOPC,C语言开发者可以更好地利用面向对象的思想进行软件设计和开发。

    算法学习资料:详解Linux内核之双向循环链表

    本文详解了 Linux 内核中双向循环链表的实现原理和使用方法,包括双循环链表的传统实现方式和 Linux 内核中的实现方式。双循环链表是一种常用的数据结构,广泛应用于操作系统、数据库、图形处理等领域。 Linux 内核...

    Linux下的两个经典宏定义.docx

    在Linux环境下,有两个经典的宏定义,它们分别是`offsetof`和`container_of`,这两个宏在系统内核编程和底层开发中非常常见。 1. `offsetof`宏定义: `offsetof`宏的主要作用是计算一个结构体成员相对于结构体起始...

    深度剖析C语言结构体

    Linux内核的实现博大精深,从offsetof的实现到后面的container_of,为什么通过结构体的的成员就能获得整个结构体的指针呢?这就得益于offsetof宏的实现。关于这个宏,前面的博文也有讲解,但不够深入,今天的这个...

    高手笔记 结构成员变量偏移量的两个应用

    其基本原理是利用了结构体成员在内存中的相对位置。`offsetof`宏用于计算结构体成员相对于结构体起始地址的偏移量。例如,`offsetof(TYPE, MEMBER)`返回`MEMBER`在`TYPE`结构体内的偏移量(以字节为单位)。然后,...

    超全的C语言嵌入式工程师笔试面试题汇总,C语言版嵌入式工程师笔试面试题

    - 内存对齐:理解数据在内存中的排列方式,以及alignof和offsetof等关键字的应用。 4. **预处理宏** - 宏定义:学习#define的用法,以及如何使用条件编译控制代码段。 - 预处理器函数:了解#include、#ifdef、#...

    结构体偏移.docx

    这个概念对于理解和优化内存布局、处理指针运算以及理解编译器对结构体的存储策略至关重要。在编程中,尤其是在处理底层数据结构或与硬件交互时,精确掌握结构体成员的偏移对于高效编程非常关键。 结构体偏移受多种...

    C++虚函数.docx

    #### 三、虚函数的实现原理 为了实现虚函数,C++编译器采用了一种称为虚函数表(Virtual Table, vtable)的机制。虚函数表是一个数组,其中存储了类中所有虚函数的地址。每个包含虚函数的类都有一个对应的虚函数表。...

Global site tag (gtag.js) - Google Analytics