2016-01-21 77 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