永久返回函数的noreturn
属性是否必要,或者这只是一个(可能是不成熟的? - 至少对于退出,我无法想象为什么要优化)优化?
有人向我解释过,在
这样的背景下void myexit(int s) _Noreturn {
exit(s);
}
// ...
if (!p) { myexit(1); }
f(*p);
/// ...
noreturn
阻止!p
分支被优化。
但是编译器是否真的允许优化该分支?
我意识到优化它的理由是:“未定义的行为不会发生。如果p
== NULL
,则取消引用它是UB,因此p
永远不会是{{1}在这种情况下,NULL
分支不会触发“。但是,编译器不能通过假设!p
可能是一个不返回的函数(即使它没有明确标记为这样)来解决问题吗?
答案 0 :(得分:7)
这允许进行多次优化。首先,对于调用本身,这可以允许简化设置,不是所有寄存器都必须保存,可以使用jmp
指令代替call
或类似。然后调用后的代码也可以优化,因为没有分支回到正常流程。
所以是的,通常_Noreturn
是编译器的重要信息。
但是,作为对您的问题的直接回答,不,这是优化的属性,因此它不是必要的。
答案 1 :(得分:2)
Axiom:标准是C中明确定义的明确资源。
assert
,因此使用assert
定义明确。assert
有条件地调用abort
,_Noreturn
函数,因此允许这样做。assert
的每次使用都在函数内部。因此,功能可能会或可能不会返回。标准有这个例子:
_Noreturn void g (int i) { // causes undefined behavior if i <= 0
if (i > 0) abort();
}
因此有条件地返回的函数不能是_Noreturn
。
这意味着:
if
- 分支在这两种情况下,编译的程序行为都与非优化抽象C机器的行为一致,并且遵守“as-if”规则。