分析源码时碰到的小知识

在分析源码时会碰到一些代码,不纠结它并不会影响我理解源码,但是细看一下会发现它的确有一些精巧,但是当了解了它的含义之后,又发觉它很简单,不过我还是把它当作一个小知识,一点点积攒在这里。
因此,这篇文章会不断的随着我阅读源码而更新的

1. 位运算向上舍入

Objects/object.c_PyObject_NewVar函数中,它首先要用_PyObject_VAR_SIZE计算该对象所用内存,这里有另外一个宏_Py_SIZE_ROUND_UP(n, a),作用是求出n最接近的a的倍数(前提条件:n是2的幂)

#define _Py_SIZE_ROUND_UP(n, a) (((size_t)(n) + \
        (size_t)((a) - 1)) & ~(size_t)((a) - 1))

这里有点太复杂,简化一下就是下面的代码,简化的代码直接使用可能会出问题,但它比较简洁,在理解含义时看一下是不错的

#define _Py_SIZE_ROUND_UP(n, a) (n + (a-1) & ~(a-1))

举个例子,a为4(2的2次幂),则a-1的二进制是11,我们举一些例子,就可以看出它的效果了:(表格中前为二进制,后为十进制)

n n + (a-1) (n + (a-1) & ~(a-1))
100/4 111/7 100/4
101/5 1000/8 1000/8
110/6 1001/9 1000/8
111/7 1010/10 1000/8

代码重点就在通过& ~(a-1))将后两位二进制变为0,而如果不给n加(a-1),那结果就是向下舍入

2. 巧妙利用||赋值

Python/pystate.c

static PyThread_type_lock head_mutex = NULL; /* Protects interp->tstate_head */
#define HEAD_INIT() (void)(head_mutex || (head_mutex = PyThread_allocate_lock()))

有时候会碰到当一个变量值为空时赋值的需要,可能会写

if(variable == NULL)
    variable = ....;

不过其实可以使用||的一个特性让它更简洁,由于它只需要一个条件成立那么就成立,如果第一个表达式成立,第二个表达式成立与否就不重要了,所以可以不运行,所以其实可以这样写

variable || variable = ...;

当variable为NULL的时候就需要去运行第二个表达式,所以就做到了变量为空时赋值,这个特性还可以拓展的,而且我第一次知道这种办法是在学javascript的时候

你可能感兴趣的:(分析源码时碰到的小知识)