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.笔记地址