2016-01-21 61 views
0

虽然上线(光纤)调度类的工作,我发现自己写一个永远不会返回的函数:这是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]]属性的有效用法吗?如果是这样,它会以任何方式帮助吗?

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

+0

_它被“jmp”调用......这听起来不对。 – erip

+0

嗯,虽然我确定会发生一些有趣的黑客行为,但这听起来不像我会让我的项目依赖的图书馆。避免不完全依赖标准C++的第三方库并不是最坏的想法。 –

+0

可能重复的[noreturn的点是什么?](http://stackoverflow.com/questions/10538291/what-is-the-point-of-noreturn) –

回答

1

我想说这是有效的,但毫无意义。

这是有效的,因为函数没有返回。合同不能被打破。

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

0

好了,进入功能JMP是有点不可思议,但回答你的问题是

“最有可能没有”。

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

第一个功能是从不输入的(或者你在说明),这意味着默认情况下它不是一个无返回值(死编码可以被编译器删除)。

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

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

就你而言,你正在检查线程是否完成。

如果您处于通过自杀谋杀线程的情况,并且这是检查线程完成的函数,并且您从线程本身调用了此函数(自杀,我非常怀疑,因为该线程将被阻塞的时间,并永远不会完成),并且你迫使线程突然退出(操作系统具体如何做到这一点)然后是该函数确实是一个不返回,因为堆栈上的执行将不会完成。

不用说,如果你在上面的情况下,你的程序有很大的问题。

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

+0

“*这是检查线程完成的函数*”,该函数*是*线程,“返回”的唯一方法是通过中止线程。 – user5434231

+0

那么是的,这是一个不返回的函数。 – MichaelCMS