在处理线程(光纤)调度类时,我发现自己编写了一个永远不会返回的函数:
// 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]]属性的有效使用?如果是的话,会有任何帮助吗?
编辑:不是副本。我理解这个属性通常用于什么。我的问题是,在这种特殊情况下,它会做些什么吗?
发布于 2016-01-21 19:01:54
我想说的是,这是有效的,但毫无意义。
它是有效的,因为函数不返回。合同不能被打破。
这是没有意义的,因为函数从未从C++代码中调用。因此,任何调用者都不能利用函数不返回的事实,因为没有调用者。在定义函数时,编译器不需要您的帮助就可以确定while语句后面的代码是否死了,如果有的话还包括函数后置。
发布于 2016-01-21 16:44:31
嗯,输入这个函数的jmp有点奇怪,但要回答您的问题是
“很可能不会”。
为什么最有可能?因为我不相信你理解没有返回的想法,或者你错误地陈述了你的用例。
在所有函数中,没有输入(或者您正在声明),这意味着默认情况下不是不返回(编译器可以删除死代码)。
但是让我们考虑一下,您实际上是在调用这个函数而没有意识到它(通过"JMP")。
不返回函数的思想是永远不要到达作用域的尽头(或者至少不是以正常的方式)。这意味着要么整个程序在函数内终止,要么抛出一个错误(意味着函数不会以正常方式弹出堆栈)。std::terminate就是这样一个很好的例子。如果在您的函数中调用它,那么您的函数就不会返回。
在您的例子中,您正在检查线程是否已经完成。
如果您所处的场景是通过自杀杀死线程,而这是检查线程完成情况的函数,则从线程本身调用此函数(我非常怀疑,因为线程将被时间阻塞,永远不会结束),并且您正在强制线程突然退出(OS特定于如何实现),则该函数确实是不返回的,因为堆栈上的执行不会完成。
不用说,如果您在上述场景中,您的程序有很大的问题。
很可能是从另一个线程调用此函数,或者通常退出该线程,在这种情况下,函数不会是不返回的。
https://stackoverflow.com/questions/34928473
复制相似问题