这是对 noreturn 属性的有效使用吗?



在处理线程(光纤)调度类时,我发现自己编写了一个永远不会返回的函数:

// New thread, called on an empty stack
// (implementation details, exception handling etc omitted)
[[noreturn]] void scheduler::thread() noexcept
{
    current_task->state = running;
    current_task->run();
    current_task->state = finished;
    while (true) yield();
    // can't return, since the stack contains no return address.
}

此函数从不直接调用(由 thread(); 调用)。它仅在切换到新上下文后由汇编代码中的jmp"调用",因此它无法在任何地方"返回"。最后,对 yield() 的调用会检查state == finished并从线程队列中删除此线程。

这是 [[noreturn]] 属性的有效使用吗?如果是这样,它会有所帮助吗?

编辑:不重复。我了解该属性通常用于什么。我的问题是,在这种特定情况下它会做任何事情吗?

我会说它是有效的,但毫无意义。

它是有效的,因为函数不返回。合同不能被破坏。

这是没有意义的,因为该函数永远不会从C++代码中调用。因此,任何调用者都不能利用函数不返回的事实,因为没有调用者。在函数的定义点,编译器不需要您的帮助来确定 while 语句后面的代码是否失效,包括函数后插曲(如果有)。

好吧,进入函数的jmp有点奇怪,但要回答你的问题是

"很可能没有"。

为什么最有可能?因为我不相信你理解不退货的想法,或者你在错误地陈述你的用例。

所有函数中的第一个永远不会被输入(或者你是这样说的),这意味着默认情况下不是无返回的(编译器可以删除死代码)。

但是,让我们考虑一下,您实际上是在调用该函数而没有意识到它(通过"JMP")。

无返回函数的想法是永远不会到达范围的尽头(或者至少不是以正常方式)。这意味着要么整个程序在函数中终止,要么抛出错误(意味着函数不会以正常方式弹出堆栈)。std::terminate 就是这种函数的一个很好的例子。如果你在函数中调用它,那么你的函数就没有返回。

在您的情况下,您正在检查线程是否已完成。

如果您处于通过自杀谋杀线程的情况中,

并且这是检查线程完成的函数,并且您从线程本身调用此函数(自杀,我非常怀疑,因为线程会被 while 阻塞并且永远不会完成),并且您正在强制线程突然退出(操作系统具体如何做到这一点),那么是的,该函数确实是一个 否返回,因为堆栈上的执行不会完成。

不用说,如果您在上述情况下,您的程序会遇到巨大的问题。

很可能您正在从另一个线程调用此函数,或者您正在正常退出线程,在这种情况下,该函数不会是无返回的。

最新更新