php源码学习d14 宏替换

1.宏替换

#define 宏名 字符串

#define 宏名(形参列表)字符串

2.宏展开注意事项:

1)每次宏展开的结果会被重复扫描,直到没有任何可展开的宏为止

2)每展开一个宏,都会记住这次展开,在这个宏展开的结果及其后续展开中,不再对相同的宏做展开。

3)带参数的宏,先对参数做展开,除非宏定义体中包含#或者##

a) #表示将后续标识符转换为字符串

b) ##表示将两个标识符连接成一个标识符

c) 注意参数展开的结果中即使有逗号(,),也不视为参数的分隔符

4)如果宏定义中带有参数,而代码中出现同样标识符时没有参数,不识为宏。

例1:

#include<stdio.h>
#define f(a,b) a##b
#define g(a)   #a
#define h(a)  g(a)
int main()
{
       printf("%s\n",h(f(1,2)));
        // 宏h(a) 是g(a),没有#,所以需要进行宏展开
        // f(1,2) 可换为 1##2 第一次替换完为h(1##2)
        // h(1##2) 可换为 g(1##2)
        // g(1##2) 可换位 #1##2,故结果输出为12
       printf("%s\n",g(f(1,2)));   
        // 宏g(a) 有#,所以不展开
        // g(f(1,2)) 可换为 #f(1,2),故结果输出为f(1,2)
       return 0;
}

例2:

#define ZEND_MM_CHUNK_SIZE (2 * 1024 * 1024)               /* 2 MB  */
#define ZEND_MM_PAGE_SIZE  (4 * 1024)                      /* 4 KB  */
#define ZEND_MM_PAGES      (ZEND_MM_CHUNK_SIZE / ZEND_MM_PAGE_SIZE)  /* 512 */
#define ZEND_MM_FIRST_PAGE (1)

#define ZEND_MM_MIN_SMALL_SIZE		8
#define ZEND_MM_MAX_SMALL_SIZE      3072
#define ZEND_MM_MAX_LARGE_SIZE      (ZEND_MM_CHUNK_SIZE - (ZEND_MM_PAGE_SIZE * ZEND_MM_FIRST_PAGE))
######################################################################################################
# define _ZEND_BIN_ALLOCATOR_SELECTOR_START(_num, _size, _elements, _pages, size, y) \
	((size <= _size) ? _emalloc_ ## _size() :
# define _ZEND_BIN_ALLOCATOR_SELECTOR_END(_num, _size, _elements, _pages, size, y) \
	)

# define ZEND_ALLOCATOR(size) \
	ZEND_MM_BINS_INFO(_ZEND_BIN_ALLOCATOR_SELECTOR_START, size, y) \
	((size <= ZEND_MM_MAX_LARGE_SIZE) ? _emalloc_large(size) : _emalloc_huge(size)) \
	ZEND_MM_BINS_INFO(_ZEND_BIN_ALLOCATOR_SELECTOR_END, size, y)

# define _emalloc(size) \
	(__builtin_constant_p(size) ? \
		ZEND_ALLOCATOR(size) \
	: \
		_emalloc(size) \
	)

#####################################################################################################
#define ZEND_MM_BINS_INFO(_, x, y) \
	_( 0,    8,  512, 1, x, y) \
	_( 1,   16,  256, 1, x, y) \
    ...
	_(28, 2560,    8, 5, x, y) \
	_(29, 3072,    4, 3, x, y)

对以上代码中ZEND_ALLOCATOR(size)的简单理解

ZEND_MM_BINS_INFO(_ZEND_BIN_ALLOCATOR_SELECTOR_START, size, y) \
((size <= ZEND_MM_MAX_LARGE_SIZE) ? _emalloc_large(size) : _emalloc_huge(size)) \
ZEND_MM_BINS_INFO(_ZEND_BIN_ALLOCATOR_SELECTOR_END, size, y)

第一步:ZEND_MM_BINS_INFO和ZEND_MM_MAX_LARGE_SIZE宏定义体中无#替换

 

_ZEND_BIN_ALLOCATOR_SELECTOR_START( 0,    8,  512, 1, size, y) \
_ZEND_BIN_ALLOCATOR_SELECTOR_START( 1,   16,  256, 1, size, y) \
...
_ZEND_BIN_ALLOCATOR_SELECTOR_START(28, 2560,    8, 5, size, y) \
_ZEND_BIN_ALLOCATOR_SELECTOR_START(29, 3072,    4, 3, size, y) \
((size <= (ZEND_MM_CHUNK_SIZE - (ZEND_MM_PAGE_SIZE * ZEND_MM_FIRST_PAGE))) ? _emalloc_large(size) : _emalloc_huge(size)) \
_ZEND_BIN_ALLOCATOR_SELECTOR_END( 0,    8,  512, 1, size, y) \
_ZEND_BIN_ALLOCATOR_SELECTOR_END_( 1,   16,  256, 1, size, y) \
...
 _ZEND_BIN_ALLOCATOR_SELECTOR_END(28, 2560,    8, 5, size, y) \
_ZEND_BIN_ALLOCATOR_SELECTOR_END(29, 3072,    4, 3, size, y)

第二步:替换 ZEND_MM_CHUNK_SIZE、ZEND_MM_PAGE_SIZE 、ZEND_MM_FIRST_PAGE

 

_ZEND_BIN_ALLOCATOR_SELECTOR_START( 0,    8,  512, 1, size, y) \
_ZEND_BIN_ALLOCATOR_SELECTOR_START( 1,   16,  256, 1, size, y) \
...
_ZEND_BIN_ALLOCATOR_SELECTOR_START(28, 2560,    8, 5, size, y) \
_ZEND_BIN_ALLOCATOR_SELECTOR_START(29, 3072,    4, 3, size, y) \
((size <= ((2 * 1024 * 1024) - ((4 * 1024) * (1)))) ? _emalloc_large(size) : _emalloc_huge(size)) \
_ZEND_BIN_ALLOCATOR_SELECTOR_END( 0,    8,  512, 1, size, y) \
_ZEND_BIN_ALLOCATOR_SELECTOR_END_( 1,   16,  256, 1, size, y) \
...
_ZEND_BIN_ALLOCATOR_SELECTOR_END(28, 2560,    8, 5, size, y) \
_ZEND_BIN_ALLOCATOR_SELECTOR_END(29, 3072,    4, 3, size, y)

第三步:替换_ZEND_BIN_ALLOCATOR_SELECTOR_START

((size <= 8) ? _emalloc_8() :\
((size <= 16) ? _emalloc_16() :\
...
((size <= 2560) ? _emalloc_2560() :\
((size <= 3072) ? _emalloc_3072() :\
((size <= ((2 * 1024 * 1024) - ((4 * 1024) * (1)))) ? _emalloc_large(size) : _emalloc_huge(size)) \
_ZEND_BIN_ALLOCATOR_SELECTOR_END( 0,    8,  512, 1, size, y) \
_ZEND_BIN_ALLOCATOR_SELECTOR_END_( 1,   16,  256, 1, size, y) \
...
_ZEND_BIN_ALLOCATOR_SELECTOR_END(28, 2560,    8, 5, size, y) \
_ZEND_BIN_ALLOCATOR_SELECTOR_END(29, 3072,    4, 3, size, y)

第四步:替换_ZEND_BIN_ALLOCATOR_SELECTOR_END

 

((size <= 8) ? _emalloc_8() :\
((size <= 16) ? _emalloc_16() :\
...
((size <= 2560) ? _emalloc_2560() :\
((size <= 3072) ? _emalloc_3072() :\
((size <= ((2 * 1024 * 1024) - ((4 * 1024) * (1)))) ? _emalloc_large(size) : _emalloc_huge(size)) \
) \
)\
...
) \
)

第五步:整理代码

(
	(size <= 8) ? _emalloc_8() :(
		(size <= 16) ? _emalloc_16() : (
            ...
			(size <= 2560) ? _emalloc_2560() : (
				(size <= 3072) ? _emalloc_3072() :(
					(size <= ((2 * 1024 * 1024) - ((4 * 1024) * (1)))) ? _emalloc_large(size) : _emalloc_huge(size)
				)
			)
            ...
		)
	)
)

3.笔记地址

d14 宏替换

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值