gpt4 book ai didi

c++ - MSVC std::exception 不符合标准?

转载 作者:行者123 更新时间:2023-11-30 03:03:26 25 4
gpt4 key购买 nike

我实现了一个异常类 WINERR_EXCEPTION 用于抛出 GetLastError() 的运行时描述!

它按预期工作。然后我想消除不必要的分配。为此,我实现了一个临时类,它接受并存储一个由 what() 返回的 const char*

但是,当我使用我的 interim_exception 类时,std::exception 的 MSVC(c++11 开发人员预览版)实现使用 std::exception 基类成员变量(而不是 what ()) 复制描述字符串。我得到 "unknown exception" 作为 what() 的返回值。

标准说:

exception& operator=(const exception& rhs) noexcept;
Effects: Copies an exception object.
Postcondition: If *this and rhs both have dynamic type exception then strcmp(what(), rhs.what()) shall equal 0.

这与后置条件中的单词 dynamic 有关吗(我的 interim_exception 的描述不是动态分配的)或者这只是一个错误的实现?

msvc 的 std::exception::operator= () :

_EXCEPTION_INLINE exception& __CLR_OR_THIS_CALL exception::operator=(const exception& _That)
{
if (this != &_That)
{
_Tidy(); // resets members

if (_That._Mydofree) // NB. This prevents my intentions (evals to false)
{
_Copy_str(_That._Mywhat);
}
else
{
_Mywhat = _That._Mywhat;
}
}

return *this;
}

我的代码:

////////////////////////////////////////////////////////////////////////////////
// file : TstThrow.h
// purpose : implementation of class WINERR_EXCEPTION
////////////////////////////////////////////////////////////////////////////////
//

#include <windows.h>
#include <exception>
#include <stdexcept>

////////////////////////////////////////////////////////////////////////////////

namespace
{
// class interim_exception to avoid unnecessary allocations
class interim_exception
: public std::exception
{
public:
// override member : what() const
const char * what() const
//_EXCEPTION_INLINE virtual const char * __CLR_OR_THIS_CALL what() const
{ return m_What; }

interim_exception( const char* szWhat )
:m_What( szWhat ? szWhat : "" ) {}

private:
const char* m_What;

};
}

////////////////////////////////////////////////////////////////////////////////

class WINERR_EXCEPTION
: public std::exception
{
public:
DWORD ErrNo () const { return m_ErrNo; }

public:
explicit WINERR_EXCEPTION ( DWORD dwErrNo );

inline exception& operator= ( const exception& that )
{
exception::operator= ( that );
return (*this);
}

inline exception& operator= ( const char* szWhat )
{
operator= ( std::exception( szWhat )); /* this works OK */
// exception::operator= ( std::exception( szWhat )); /* this works OK */
// exception::operator= (interim_exception( szWhat )); /* this doesn't work */
// operator= (interim_exception( szWhat )); /* this doesn't work */
return (*this);
}

private:
DWORD m_ErrNo;

};

////////////////////////////////////////////////////////////////////////////////


WINERR_EXCEPTION::WINERR_EXCEPTION ( DWORD dwErrNo )
:m_ErrNo (dwErrNo) //exception("") ,
{
DWORD dwFrmtFlags (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER);
dwFrmtFlags |= FORMAT_MESSAGE_IGNORE_INSERTS;
dwFrmtFlags |= FORMAT_MESSAGE_MAX_WIDTH_MASK; // no newlines

LPSTR pBuffer (nullptr);
if (! ::FormatMessageA( dwFrmtFlags ,nullptr
,dwErrNo ,0 ,(LPSTR)&pBuffer ,0 ,nullptr ))
{
dwErrNo = GetLastError();
if (dwErrNo == ERROR_MR_MID_NOT_FOUND)
operator= ( WINERR_EXCEPTION( dwErrNo ).what() );
else
operator= ( "Substituted Error Message :\n\t"
"Could not allocate buffer for ORIGINAL Error Message\n" );
}
else
{
operator= ( pBuffer );
LocalFree( pBuffer );
}
}

////////////////////////////////////////////////////////////////////////////////

我的测试:

void     TstThrow ()
{
for ( DWORD dwErr = ERROR_SUCCESS; dwErr < 200; ++dwErr )
{
SetLastError( dwErr );
try
{
throw ::WINERR_EXCEPTION( GetLastError() );
}
catch (const ::WINERR_EXCEPTION& werr)
{
::WINERR_EXCEPTION err ( werr ); // test for copying of object !

std::cout << std::setw(4) << werr.ErrNo() << " :"<< werr.what() << std::endl;
}

if ((dwErr % 100) == 0)
Sleep(1500);
}
}

最佳答案

如果两个对象的动态类型都是exception,则这两个对象“都具有动态类型exception” ,而不是异常的子类型。所以后置条件不适用于你的情况,因为动态类型是 WINERR_EXCEPTION , 不是 exception .

如果你想要what()返回 std::exception() 提供的默认值以外的内容,那么你必须自己覆盖它,或者从覆盖它的东西继承,比如 <stdexcept> 中定义的异常类型. (至少在标准 C++ 中是这样;我不知道微软对 std::exception 的扩展应该如何工作,所以我不能对它们发表评论)。

关于c++ - MSVC std::exception 不符合标准?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9367545/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com