Python源码阅读-基础1
#ifndef Py_OBJECT_H#define Py_OBJECT_H······//一段代码#endif//代码格式1
如果没有定义Py_OBJECT_H那么就定义Py_OBJECT_H , 然后运行里边的内容;如果下次还走到这个文件 , 进行#ifndef判断后 , 里边的内容就不会运行 。
通过这种方法 , 第一次使用这个头文件的c文件 , 编译时 , 查看是否定义Py_OBJECT_H;
第一次肯定没有 , 所以它就定义了头文件里面的相关宏以及变量;第二个C文件使用这个头文件时 , 编译时 , 一看Py_OBJECT_H已经存在 , 说明我们需要使用的东西已经存在 , 不需要定义了 , 直接使用就可以了 , 这样问题就解决了 。
#ifdef __cplusplusextern "C" {#endif/* Object and type object interface */······//一段代码#ifdef __cplusplus}#endif//代码格式2
__cplusplus是CPP中的自定义宏 , 如果定义了这个宏 , 表示这是一段CPP代码 。 上面这个格式的意思是:如果这是一段CPP代码 , 那么加入 extern "C" {}处理其中代码 。
extern "C" {}的作用就是告诉C++编译器括号里的内容是按照C的obj编译的 , 要链接的话按照C的命名规则去找 。
【Python源码阅读-基础1】那么C++的命名规则和C的命名规则有何不同?这得从CPP支持函数的重载处理讲起 , C++中为了支持重载机制 , 在编译生成的汇编文件中 , 要对函数名进行一些特殊处理 , 比如加入函数的返回类型等等(fun_int());而在C中只是简单函数名(fun()),不会加入其它信息 。
结论:C++和C对产生的函数名的处理不一样 , 加入代码格式2就是为了实现C和C++的互相调用问题 。
#ifdef Py_TRACE_REFS/* Define pointers to support a doubly-linked list of all live heap objects.(双向链表用于支持所有活跃堆对象)*/#define _PyObject_HEAD_EXTRA\struct _object *_ob_next;\struct _object *_ob_prev;#define _PyObject_EXTRA_INIT 0, 0,#else#define _PyObject_HEAD_EXTRA#define _PyObject_EXTRA_INIT#endif//代码格式3
如果定义了Py_TRACE_REFS , _PyObject_HEAD_EXTRA才不空 , 宏展开为两个指针 , 两个指针看着是实现双向链表的 , 将所有活跃堆对象用双向链表链接起来 。 如果没有定义Py_TRACE_REFS , _PyObject_HEAD_EXTRA为空 。
/* Py_DEBUG implies Py_REF_DEBUG. */#if defined(Py_DEBUG) && !defined(Py_REF_DEBUG)#define Py_REF_DEBUG#endif#if defined(Py_LIMITED_API) && defined(Py_REF_DEBUG)#error Py_LIMITED_API is incompatible with Py_DEBUG, Py_TRACE_REFS, and Py_REF_DEBUG#endif//代码格式4
从这段代码可以看出 , _PyObject_HEAD_EXTRA这个宏的作用为 , 在Debug模式下 , 将所有活跃堆对象用双向链表链接起来 , 方便Debug 。
推荐阅读
- Git服务器配置错误导致日产汽车源码在网上泄露
- 计算机专业大一下学期,该选择学习Java还是Python
- 想自学Python来开发爬虫,需要按照哪几个阶段制定学习计划
- 未来想进入AI领域,该学习Python还是Java大数据开发
- 充值|APP会员充值需注意这三点
- 2021年Java和Python的应用趋势会有什么变化?
- 非计算机专业的本科生,想利用寒假学习Python,该怎么入手
- 用Python制作图片验证码,这三行代码完事儿
- 手把手配置HLS流媒体服务器
- 历时 1 个月,做了 10 个 Python 可视化动图,用心且精美...