Great idea! But let's stay classy.

Also:
* Use MAME_DEBUG to flag it
* Report errors by throwing an emu_fatalerror, so that we get
   the standard useful behaviors (break in debugger, caught
   during validation, stack crawls, etc)
This commit is contained in:
Aaron Giles 2012-08-13 06:13:50 +00:00
parent 3258eb6014
commit 524f627a23
2 changed files with 18 additions and 18 deletions

View File

@ -12,16 +12,14 @@
#include "emu.h" #include "emu.h"
void bitch_bad_cast(const std::type_info &src_type, const std::type_info &dst_type) void report_bad_cast(const std::type_info &src_type, const std::type_info &dst_type)
{ {
fprintf(stderr, "Error: bad downcast<> or device<>. Tried to convert a %s to a %s, which are incompatible.\n", throw emu_fatalerror("Error: bad downcast<> or device<>. Tried to convert a %s to a %s, which are incompatible.\n",
src_type.name(), dst_type.name()); src_type.name(), dst_type.name());
abort();
} }
void bitch_bad_device_cast(const device_t *dev, const std::type_info &dst_type) void report_bad_device_cast(const device_t *dev, const std::type_info &dst_type)
{ {
fprintf(stderr, "Error: bad downcast<> or device<>. Tried to convert the device %s of type %s to a %s, which are incompatible.\n", throw emu_fatalerror("Error: bad downcast<> or device<>. Tried to convert the device %s of type %s to a %s, which are incompatible.\n",
dev->tag(), dev->name(), dst_type.name()); dev->tag(), dev->name(), dst_type.name());
abort();
} }

View File

@ -334,20 +334,21 @@ private:
class device_t; class device_t;
void bitch_bad_cast(const std::type_info &src_type, const std::type_info &dst_type); void report_bad_cast(const std::type_info &src_type, const std::type_info &dst_type);
void bitch_bad_device_cast(const device_t *dev, const std::type_info &dst_type); void report_bad_device_cast(const device_t *dev, const std::type_info &dst_type);
// template function for casting from a base class to a derived class that is checked // template function for casting from a base class to a derived class that is checked
// in debug builds and fast in release builds // in debug builds and fast in release builds
template<class _Dest, class _Source> template<class _Dest, class _Source>
inline _Dest downcast(_Source *src) inline _Dest downcast(_Source *src)
{ {
#ifndef NDEBUG #ifdef MAME_DEBUG
if(dynamic_cast<_Dest>(src) != src) { if (dynamic_cast<_Dest>(src) != src)
if(dynamic_cast<const device_t *>(src)) {
bitch_bad_device_cast(dynamic_cast<const device_t *>(src), typeid(_Dest)); if (dynamic_cast<const device_t *>(src) != NULL)
report_bad_device_cast(dynamic_cast<const device_t *>(src), typeid(_Dest));
else else
bitch_bad_cast(typeid(src), typeid(_Dest)); report_bad_cast(typeid(src), typeid(_Dest));
} }
#endif #endif
return static_cast<_Dest>(src); return static_cast<_Dest>(src);
@ -356,12 +357,13 @@ inline _Dest downcast(_Source *src)
template<class _Dest, class _Source> template<class _Dest, class _Source>
inline _Dest downcast(_Source &src) inline _Dest downcast(_Source &src)
{ {
#ifndef NDEBUG #ifdef MAME_DEBUG
if(&dynamic_cast<_Dest>(src) != &src) { if (&dynamic_cast<_Dest>(src) != &src)
if(dynamic_cast<const device_t *>(&src)) {
bitch_bad_device_cast(dynamic_cast<const device_t *>(&src), typeid(_Dest)); if (dynamic_cast<const device_t *>(&src) != NULL)
report_bad_device_cast(dynamic_cast<const device_t *>(&src), typeid(_Dest));
else else
bitch_bad_cast(typeid(src), typeid(_Dest)); report_bad_cast(typeid(src), typeid(_Dest));
} }
#endif #endif
return static_cast<_Dest>(src); return static_cast<_Dest>(src);