__builtin_trap:何时使用它?

Dev*_*ark 17 c++ gcc built-in

gcc提供了"用于优化"的其他内置函数.

其中之一就是void __builtin_trap (void)通过执行非法命令来中止程序.

来自doc:

__builtin_trap函数导致程序异常退出.GCC通过使用依赖于目标的机制(例如故意执行非法指令)或通过调用abort来实现此功能.使用的机制可能因版本而异,因此您不应依赖任何特定实现.

为什么你会永远使用此,而不是exit(1)abort?为什么gcc开发人员将此视为优化功能?

Guv*_*nte 8

因为exit(1)导致程序正常终止并带有错误状态代码.请参阅cppreference页面.相反,__builtin_trap导致程序异常终止.

看待差异的最简单方法是查看所做的保证exit,如果做其中一件事你不想发生,__builtin_trap那就更好了.

调试是最常见的示例,因为__builtin_trap可能触发调试器转储进程,而exit不会(因为程序"正常"终止并出现错误).

  • 由于存在错误,`abort`将是一种更便携的方式,可以立即杀死进程.我怀疑`__builtin_trap`是因为`abort`是一个库函数,而GCC不能总是指望标准库上的链接. (4认同)
  • Linux 上的 @Revolver_Ocelot glibc 通过删除所有信号处理程序然后向进程发送“SIGTRAP”信号来实现它,该信号终止进程(尽管调试器通常会中断)。之后它还会向自己发送“SIGKILL”,然后无限循环,以防万一。我想“__builtin_trap”会使用陷阱指令(如果可用)。 (2认同)

Mat*_*son 6

这些__builtin函数不一定是为了优化 - 它们是为了“做编译器无法直接从源代码做的事情”,包括支持“特殊指令”和“特定于体系结构的操作”。函数的主要目的之一__builtin是编译器将“知道”它们在稍后阶段的作用。尽管编译器中有“库优化”,但编译器可以__builtin更自由地使用函数来确定行为是否特定 - 例如,__builtin_trap可以依赖“不继续下一条指令”,因此编译器不会'不必担心像这样的代码:

if (x <= 0.0) __builtin_trap();
y = ln(x);
Run Code Online (Sandbox Code Playgroud)

然后它可以使用“快速内联版本ln”,因为错误已经被捕获。

另请注意,__builtin_trap几乎肯定会在调试器中以“停止”的形式结束,其中exit(1)或某些此类内容将仅以“不成功”结果代码退出程序,如果您试图弄清楚数学在哪里,这是相当烦人的错误消息来自...

  • 我保证编译器会假设`__builtin_trap`不会继续 - 是的,你可以捕获它,并且可以继续,但是由于编译器不期望它,你得到了你应得的,并且它仍然会假设` x &gt; 0.0`。`__builtin_trap` 是编译器知道您正在使用例如 `assert` 的方式。 (4认同)