diff options
Diffstat (limited to 'zen/file_error.h')
-rw-r--r-- | zen/file_error.h | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/zen/file_error.h b/zen/file_error.h index d8c6224c..7be52282 100644 --- a/zen/file_error.h +++ b/zen/file_error.h @@ -36,14 +36,23 @@ DEFINE_NEW_FILE_ERROR(ErrorFileLocked); DEFINE_NEW_FILE_ERROR(ErrorDifferentVolume); -//CAVEAT: evalulate global error code *before* "throw" statement which may overwrite error code -//due to a memory allocation before it creates the thrown instance! (e.g. affects MinGW + Win XP!!!) -template <class FE = FileError> inline -void throwFileError(const std::wstring& msg, const std::wstring& functionName, const ErrorCode ec) //throw FileError -{ - throw FE(msg, formatSystemError(functionName, ec)); -} +//CAVEAT: thread-local Win32 error code is easily overwritten => evaluate *before* making any (indirect) system calls: +//-> MinGW + Win XP: "throw" statement allocates memory to hold the exception object => error code is cleared +//-> VC 2015, Debug: std::wstring allocator internally calls ::FlsGetValue() => error code is cleared +#ifdef _MSC_VER +#define THROW_LAST_FILE_ERROR(msg, functionName) \ + do \ + { \ + const ErrorCode ecInternal = getLastError(); \ + throw FileError(msg, formatSystemError(functionName, ecInternal)); \ + \ + __pragma(warning(suppress: 4127)) /*"conditional expression is constant"*/ \ + } while (false) +#else //variant witout "__pragma": +#define THROW_LAST_FILE_ERROR(msg, functionName) \ + do { const ErrorCode ecInternal = getLastError(); throw FileError(msg, formatSystemError(functionName, ecInternal)); } while (false) +#endif //----------- facilitate usage of std::wstring for error messages -------------------- |