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

时间:2016-01-21 16:01:27

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

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

2 个答案:

答案 0 :(得分:1)

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

它是有效的,因为该函数不会返回。合同无法破解。

这是没有意义的,因为函数永远不会从C ++代码调用。因此没有调用者可以利用函数不返回的事实,因为没有调用者。在定义函数时,编译器不应该要求您的帮助来确定while语句后面的代码是否已经死亡,包括函数postlude(如果有的话)。

答案 1 :(得分:0)

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

"很可能没有"。

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

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

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

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

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

如果您正处于通过自杀谋杀线程的情况,这是检查线程完成的函数,并且您从线程本身调用此函数(自杀,我非常怀疑,因为线程将被while阻塞而永远不会完成),并且你正在强制线程突然退出(OS具体如何做)然后是函数确实是一个无法返回,因为堆栈上的执行不会成为结束。

毋庸置疑,如果您在上述情况下,您的程序会出现巨大问题。

很可能你是从另一个线程调用这个函数,或者你正在退出正常的线程,这个函数不会是一个不返回的。