__declspec(noreturn)的用法
飄飄白雲 2008.11.26 先來看noreturn在MSDN中的註解:
一個函數被
__declspec(noreturn)所約定,那麼它的含義是告訴編譯器,這個函數不會返回,其結果是讓編譯器知道呼叫慣例為
__declspec(noreturn)的函數之後的代碼不可到達。
如果編譯器發現一個函數有無傳回值的代碼分支,編譯器將會報C4715的警告,或者C2202的錯誤資訊。如果這個代碼分支是因為函數不會返回從而無法到達的話,可以使用約定
__declspec(noreturn)來避免上述警告或者錯誤。
| 注意: |
將一個期望返回的函數約定為 __declspec(noreturn) 將導致未定義的行為。 |
樣本:
在下面的這個例子中,main函數沒有從else 分支返回,所以約定函數fatal為__declspec(noreturn)來避免編譯或警告資訊。
// noreturn2.cpp__declspec(noreturn) extern void fatal () {}int main() { if(1) return 1; else if(0) return 0; else fatal();} -----------------------------------------------------------另一個用途就是在自訂exception的時候,可以用
__declspec(noreturn)來約定throw函數,因而可以在拋出異常的時候,讓其後的語句不被執行。 樣本:
- // Exception
- class Exception {
- public:
- virtual~Exception()
- {
- }
- };
- // Exception
- // LogicalError
- class LogicalError :
- public Exception {
- CStringW m_Message;
- public:
- LogicalError(LPCWSTR msg) :
- m_Message(msg)
- {
- }
- virtual~LogicalError()
- {
- }
- LPCWSTR GetMessage() const
- {
- return m_Message;
- }
- static void DECL_NORETURN Throw(LPCWSTR msg)
- {
- throw LogicalError(msg);
- }
- };
在使用的時候,就可以達到在調用throw之後,位於throw語句之後代碼不會被執行。
比如:LPCWSTR getString(FILE* fp){ if( fp == NULL) { LogicalError::Throw(L"getString(FILE* fp):File handle fp is NULL!"); } ......}