菜单开关

周梦康 发表于 2017-10-30 1156 次浏览 标签 : Cphp

免费领取阿里云优惠券 我的直播 - 《PHP 进阶之路》

文件位置:Zend/zend_alloc.h

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

__builtin_constant_p 是编译器gcc内置函数,用于判断一个值是否为编译时常量,如果是常数,函数返回1 ,否则返回0。

看似很诡异,怎么循环嵌套这个宏的定义了呢?实际这里是有一个和_emalloc宏同名的函数

文件位置:Zend/zend_alloc.c

ZEND_API void* ZEND_FASTCALL _emalloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
{
//...
}

上面ZEND_FILE_LINE_DCZEND_FILE_LINE_ORIG_DC debug 调试使用,非 debug 模式为空。

demo 1

#include <stdio.h>

void _emalloc(int size)
{
    printf("function %d\n",size);
}

# define ZEND_ALLOCATOR(size) printf("ZEND_ALLOCATOR %d\n",size)

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

int main(int argc, char const *argv[])
{
    
    _emalloc(12);
    
    int a = 2;
    _emalloc(a);
    
    return 0;
}

运行输出结果与预期相符

ZEND_ALLOCATOR 12
function 2

demo 2

#include <stdio.h>

void _emalloc(int size);

# define ZEND_ALLOCATOR(size) printf("ZEND_ALLOCATOR %d\n",size)

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

int main(int argc, char const *argv[])
{
    
    _emalloc(12);
    
    int a = 2;
    _emalloc(a);
    
    return 0;
}

void _emalloc(int size)
{
    printf("function %d\n",size);
}

无法运行
PHP 源码碎片 - 从 _emalloc 的宏定义看同名函数与宏

总结

编译通过的前提:同名函数在同名宏前面定义,否则宏无法正确展开。

嗨,老铁,欢迎来到我的博客!

如果觉得我的内容还不错的话,可以关注下我在 segmentfault.com 上的直播。我主要从事 PHP 和 Java 方面的开发,《深入 PHP 内核》作者之一。

[视频直播] PHP 进阶之路 - 亿级 pv 网站架构的技术细节与套路 直播中我将毫无保留的分享我这六年的全部工作经验和踩坑的故事,以及会穿插着一些面试中的 考点难点加分点

评论列表

回复 daryl 2017-10-30 11:01:22
感谢 dalao 的文章。最近入了 zend string 的坑,然后就慢慢到这里了
回复 梦康 2017-10-30 14:30:46
回复daryl: 一起学习~~~~ C 好多东西都查不知道~