如果有
[[noreturn]]
(C2X,n3301),那为什么没有[[always_return]]
?
[[always_return]]
的语义可能如下:
使用
属性声明的函数应始终返回到其调用者。[[always_return]]
[[always_return]]
的基本原理是提示编译器执行优化。
示例(取自N3128):
extern void g(int x);
int f(int a, int b)
{
g(b ? 42 : 43);
return a / b;
}
编译器可以自由(乐观地)假设 UB 不会发生。
但是,只有当 UB 发生时(即存在于抽象机器级别的执行中),UB 的任何(危险)后果才会发生。
在此示例中,
g
可能会终止程序(即不返回)。因此,据我了解,编译器可能不会将b ? 42 : 43
折叠到42,因为在抽象机器级别a / b
可能不会被执行,因此编译器可能不会传播/使用b
是非的假设-零。
但是,如果
g
是用 [[always_return]]
声明的,那么,据我了解,编译器 may 将 b ? 42 : 43
折叠到 42,因为在抽象机器级别 a / b
总是 执行,因此编译器 may传播/使用 b
非零的假设。
附注同样的问题也适用于
[[may_return]]
。
如果有
(C2X,n3301),那为什么没有[[noreturn]]
?[[always_return]]
最终,因为委员会没有看到添加这样一个属性的(足够)价值。 我倾向于猜测他们没有看到价值,因为它甚至没有被提议,但如果它被提议,那么它就会被拒绝。 当然,添加
[[noreturn]]
的提议并没有考虑到 [[always_return]]
。
为什么会这样呢?用户函数无法确保它始终返回。 程序总是有可能在函数执行期间被终止,或者通过调试器阻止其返回,或者函数程序员无法控制的任何其他事情碰巧阻止了函数返回。
这有什么好处呢?在缺乏特定函数的任何属性和/或特殊知识的情况下,C 实现必须假定函数调用将返回。但即使
[[always_return]]
的承诺实际上可以可靠地兑现,这些信息对实施也没有什么用处。 就像我断言明天太阳会升起一样。 即使假设你基于这些理由对我有绝对的信心,你会采取不同的做法吗?不,因为无论在多大程度上它都会产生影响,你已经将其视为一个可行的假设。
[[noreturn]]
不同。 相对于未标记的功能(根据设计,不会返回),它提供了性能增强和改进的诊断。
此外,
[[noreturn]]
属性是C11以来C语言中的_Noreturn
函数说明符的替代品,因此它并不是真正的新功能。 切换到属性而不是说明符支持与 C++ 的协调。 没有类似于您假设的 [[always_return]]
的函数说明符。