0

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

// 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]]属性的有效使用吗?如果是这样,它会以任何方式帮助吗?

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

4

2 回答 2

1

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

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

这是没有意义的,因为该函数永远不会从 C++ 代码中调用。所以没有调用者可以利用函数不返回的事实,因为没有调用者。并且在函数的定义点,编译器不应该需要你的帮助来确定while语句后面的代码是死的,包括函数后奏(如果有的话)。

于 2016-01-21T19:01:54.053 回答
0

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

“很可能没有”。

为什么最有可能?因为我不相信您理解不归路的想法,或者您错误地陈述了您的用例。

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

但是让我们考虑一下您实际上是在没有意识到的情况下调用该函数(通过那个“JMP”)。

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

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

如果您处于通过自杀谋杀线程的情况,这是检查线程完成的函数,并且您从线程本身调用此函数(自杀,我非常怀疑,因为线程将成为被while阻塞并且永远不会完成),并且您正在强制线程突然退出(特定于操作系统的如何执行此操作)然后是的,该函数确实是无返回的,因为堆栈上的执行不会完成。

不用说,如果您处于上述情况,您的程序会遇到很大的问题。

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

于 2016-01-21T16:44:31.233 回答