__declspec(noreturn)的用法

__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函数,因而可以在抛出异常的时候,让其后的语句不被执行。
 
示例:
  1. // Exception
  2. class Exception {
  3. public:
  4.     virtual~Exception()
  5.     {
  6.     }
  7. };
  8. // Exception
  9. // LogicalError
  10. class LogicalError :
  11.     public Exception {
  12.     CStringW m_Message;
  13. public:
  14.     LogicalError(LPCWSTR msg) :
  15.     m_Message(msg)
  16.     {
  17.     }
  18.     virtual~LogicalError()
  19.     {
  20.     }
  21.     LPCWSTR GetMessage() const
  22.     {
  23.         return m_Message;
  24.     }
  25.     static void DECL_NORETURN Throw(LPCWSTR msg)
  26.     {
  27.         throw LogicalError(msg);
  28.     }
  29. };
在使用的时候,就可以达到在调用throw之后,位于throw语句之后代码不会被执行。
 
比如:
LPCWSTR getString(FILE* fp)
{
    if( fp == NULL) {
        LogicalError::Throw(L"getString(FILE* fp):File handle fp is NULL!");
    }
    
    ......
}
 

你可能感兴趣的:(c,exception,File,null,FP,编译器)