首页 > 编程语言 >C++学习---cstdbool和cstddef源码学习分析

C++学习---cstdbool和cstddef源码学习分析

时间:2022-12-05 23:02:07浏览次数:65  
标签:cstddef __ member defined --- 源码 size type define

引言

cstdbool是C++对stdbool.h头文件的封装,里面定义了与bool变量相关的宏;

cstddef是C++对stddef.h头文件的封装,里面定义一些特殊类型(如size_t),有用的宏函数(offsetof)。

平时我们都是使用这些宏或者宏函数,对于它们的原理还不是很清楚,是怎么实现这些功能的呢?接下来我们就一一来看一看源码实现。

stdbool.h

cstdbool实现

代码参考:​​www.aospxref.com/android-13.…​

在cstdbool文件中的逻辑很简单,解除__bool_true_false_are_defined的定义,然后将其定义为1,标识bool,true,false都已经被C++定义了。

23 #include <__config>
24
25 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
26 #pragma GCC system_header
27 #endif
28
29 #undef __bool_true_false_are_defined
30 #define __bool_true_false_are_defined 1
31

C语言的原生实现stdbool.h

参考代码:​​www.aospxref.com/android-13.…​​ 在该文件中,如果当前不是C++环境,那么我们将bool/true/false都进行定义,同时将__bool_true_false_are_defined定义为1,以便后续使用。

4  #ifndef __cplusplus
5
6 #define true 1
7 #define false 0
8 #define bool _Bool
9
10 #endif
11
12 #define __bool_true_false_are_defined 1

总结

stdbool.h实际上是为了解决C/C++的兼容问题出现的。

stddef.h

代码参考:​​www.aospxref.com/android-13.…​

常量NULL的定义

从这里可以看出,实际上NULL有三种实现方式,0L,((void*)0)都是我们在C语言中常用的方式,其中的nullptr是C++定义的内部类型,能够做到对很多情况的适配,不是一个单独的基本类型。

4  #if __cplusplus >= 201103L
5 #define NULL nullptr
6 #elif defined(__cplusplus)
7 #define NULL 0L
8 #else
9 #define NULL ((void*)0)
10 #endif

类型的定义

其中定义了如下的类型:

  • ptrdiff_t---保存指针减法的结果
  • size_t---无符号整数,表示类型占据的size大小
  • max_align_t---最大默认对齐的类型
  • nullptr_t---C++中的空指针类型 参考代码:www.aospxref.com/android-13.…

x86_64的相关实现如下: ptrdiff_t使用long定义,指针减法,实际上是64位数的减法,long足够表示; size_t使用long表示; max_align_t定义为拥有long long数据和long double数据的结构体; nullptr_t定义为nullptr的类型。

1  #define _Addr long59  #if defined(__NEED_ptrdiff_t) && !defined(__DEFINED_ptrdiff_t)
60 typedef _Addr ptrdiff_t;
61 #define __DEFINED_ptrdiff_t
62 #endif49 #if defined(__NEED_size_t) && !defined(__DEFINED_size_t)
50 typedef unsigned _Addr size_t;
51 #define __DEFINED_size_t
52 #endif40 #if defined(__NEED_max_align_t) && !defined(__DEFINED_max_align_t)
41 typedef struct { long long __ll; long double __ld; } max_align_t;
42 #define __DEFINED_max_align_t
43 #endiftypedef decltype(nullptr) nullptr_t;

offsetof宏

offsetof (type,member)接受两个参数,类型和成员名,返回该成员的偏移地址。

听上去这个实现起来很简单,我们来看看这个精巧的宏是如何设计的。

21  #if __GNUC__ > 3
22 #define offsetof(type, member) __builtin_offsetof(type, member)
23 #else
24 #define offsetof(type, member) ((size_t)( (char *)&(((type *)0)->member) - (char *)0 ))
25 #endif

不考虑使用内建函数实现的方式,我们来看看第二种方式,这是一个比较复杂的宏,让我们来一步步拆开它,并体会其中的精妙:

((size_t)( (char *)&(((type *)0)->member) - (char *)0 ))

第一步:返回值类型强转为size_t,规范为byte数,也即是偏移量;

(char *)&(((type *)0)->member) - (char *)0

第二步:char*指针转换然后做减法,得到byte数的差值;

第三步:((type )0)->member这里使用了0指针强转为type指针,然后指向成员member,此时这个变量的地址相当于0+member偏移,然后取地址,指针转换为char*后做减法

这个方法的好处在于,只使用了0指针,没有通过其它变量的构造,很简单地找到了偏移地址,而且这个过程中做的每一步类型转换都是必要的。具体细节读者可以再品味一下,这也是我们阅读源码的收获。

标签:cstddef,__,member,defined,---,源码,size,type,define
From: https://blog.51cto.com/u_15830688/5913323

相关文章

  • Selenium4+Python3系列(十一) - Page Factory设计模式
    写在前面:PageObject模式,目的是将元素定位和元素操作分层,只接触测试内容,不写基础内容,便于后续对自动化测试用例体系的维护,这是中心思想,也是核心。那么我们继续将简洁延续,......
  • ABAP-OpenSQL-select查询操作
    *&---------------------------------------------------------------------**&ReportZ13*&*&-----------------------------------------------------------------......
  • 日志-2022-12
    1,青蛙......
  • Selenium4+Python3系列(十一) - Page Factory设计模式
    写在前面:PageObject模式,目的是将元素定位和元素操作分层,只接触测试内容,不写基础内容,便于后续对自动化测试用例体系的维护,这是中心思想,也是核心。那么我们继续将简洁延续......
  • 情绪日志-2022-12
    情绪......
  • php版高校宿舍管理系统源码(文末有下载方式)
    大家好,我是程序猿零壹。分享一款高校宿舍管理系统,该系统使用php+mysql开发,实现了学生宿舍管理的功能模块,包含学生管理、楼宇管理、宿舍管理、宿舍分配,物品出入登记、来访......
  • 矩阵分析-7
    泰勒级数展开向量形式矩阵形式方向导数极值强极小值如果标量......
  • Spring源码-03-容器创建
    Spring源码-03-容器创建注解Bean方式publicclassAnnotationCtxMain02{ publicstaticvoidmain(String[]args){ newAnnotationConfigApplicationContext(MyCf......
  • Spring源码-02-Bean容器
    Spring源码-02-Bean容器一类关系二宏观视角......
  • Spring源码-04-注解Bean读取器
    Spring源码-04-注解Bean读取器AnnotatedBeanDefinitionReader一构造方法publicAnnotatedBeanDefinitionReader(BeanDefinitionRegistryregistry,Environmentenviro......