这个问题的标题可能有点奇怪,但问题是,据我所知,根本没有任何东西反对尾部调用优化.然而,在浏览开源项目时,我已经遇到了一些主动try 阻止编译器进行尾部调用优化的函数,例如CFRunLoopRef的实现,其中充满了这样的hacks.例如:

static void __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__() __attribute__((noinline));
static void __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__(CFRunLoopObserverCallBack func, CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info) {
    if (func) {
        func(observer, activity, info);
    }
    getpid(); // thwart tail-call optimization
}

我很想知道为什么这看起来如此重要,有没有什么情况是我作为一个normal开发人员也应该记住这一点的?例如.尾部调用优化有没有常见的trap ?

推荐答案

我在这里的猜测是,出于调试目的,它是为了确保__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__在堆栈跟踪中.它有__attribute__((no inline))个支持这一 idea 的人.

如果你注意到的话,这个函数只是go 跳转到另一个函数,所以这是一种蹦床形式,我只能认为它有这样一个详细的名字来帮助调试.鉴于函数正在调用从其他地方注册的函数指针,因此该函数可能无法访问调试符号,这将特别有用.

还要注意做类似事情的其他名称相似的函数-它看起来真的很像是为了帮助查看回溯发生了什么.请记住,这是MacOSX的核心代码,也会出现在崩溃报告和进程示例报告中.

C++相关问答推荐

在C、Linux中同步进程

是否可以在C中进行D3 D12申请?

了解一些CLIPS原语数据类型

如何判断宏参数是否为C语言中的整型文字

C中是否有语法可以直接初始化一个常量文本常量数组的 struct 成员?

__VA_OPT__(,)是否可以检测后面没有任何内容的尾随逗号?

在C中将通用字符名称转换为UTF-8

为什么sscanf不能正确地从这个字符串格式中提取所有数字?

将宏值传递给ARM链接器,该链接器将变量放置在特定位置

对重叠字符串使用MemMove

函数的限制限定指针参数允许优化调用方函数吗?

';\n&39;和';\r&39;中的';\n&39;之间有什么关系?

为什么编译器不能简单地将数据从EDI转移到EAX?

`预期说明符-限定符-列表在‘(三元运算符中的’token`‘之前

如何在C中定义指向函数的指针并将该指针赋给函数?

`%%的sscanf无法按预期工作

中位数和众数不正确

从管道读取数据时丢失

GDB 用内容初始化数组

如何在 C 中的 Postgres 函数的表中 for 循环