Kay-Uwe Kasemir wrote:
- what() gives a user-readable message.
There, I would actually require the specific
const char *what();
because that's what std::exception happens to use.
The problems with using the std::exception::what() are how/when to do
the conversion to char*, and in a low memory situation the act of
allocating the storage for the string itself may fail resulting in a
bad_alloc exception instead of the one we wanted to throw. Jeff would
also mention the issue of giving out pointers to internal storage...
By making our what() take a StringEditor reference instead of returning
char* we don't have to worry about the string buffer in the exception
class. You can still obtain and print out the string that you're after,
but your catch clause has to provide the storage for the message.
In some circumstances a catch clause is able to recover from certain
exceptions without having to report or log anything at all; for these
cases the conversion to ASCII would not be wasted cycles, so IMHO the
exception class' constructor shouldn't be doing that.
I'm looking at the possibility of supporting both a const char* what()
and the StringEditor version, by implementing the former in terms of the
latter. The BaseException object would include a mutable VariableString
cache which is only allocated if the std::exception::what() routine gets
called.
The archiver is being reworked to use something like this:
<snip>
... because I happen to like source & line info as well as a printf-type
interface for generating the message,
How do you decide how big a string buffer to allocate, and what if you
run out of memory in the exception class' constructor?
Does the file & line information actually have to be included in the
thrown object? I notice that in 3.15 Jeff is using a macro called
'epicsThrowTrace' for all throws inside his code; the macro calls a
function before throwing the actual exception object:
#define epicsThrowTrace epicsThrowLocTrace(__FILE__, __LINE__); throw
The epicsThrowLocTrace() function conditionally calls errlogPrintf() to
log the throw's file & line number based on a global setting. This
design doesn't burden the compiler with copying the file and line number
into the exception object; lets face it, that data is of absolutely no
use to the catch() handler, so why throw it in the first place?
but the primary interface to that info is the what() that comes
with the std::exception.
I'm starting to think you're right there, but I like the idea of being
able to postpone the string conversion so it can go straight into the
catcher's buffer. It occurs to me that a future version of errlog could
implement the StringEditor API which we could then plug straight into
the exception's what() routine.
Here's my latest version:
class BaseException :
public std::exception {
public:
virtual ~BaseException() throw() {}
virtual void what(StringEditor &str) const;
virtual long status() const;
virtual const char* what() const throw();
private:
mutable VariableString whatCache;
};
const char* BaseException::what() const throw() {
if (whatCache.size() == 0) {
try {
whatCache.reserve(128); // FIXME
what(whatCache);
}
catch (std::bad_alloc &exc) {
return "BaseException: Out of memory";
}
catch (...) {
return "BaseException: what(StringEditor) threw...";
}
}
return whatCache.c_str();
}
void BaseException::what(StringEditor &str) const {
str += "BaseException: Something went wrong...";
}
long BaseException::status() const {
return S_exc_exception;
}
--
There is no S in exprexxo.
- Replies:
- Re: 3.15 C++ Exception classes Kay-Uwe Kasemir
- References:
- 3.15 C++ Exception classes Andrew Johnson
- Re: 3.15 C++ Exception classes Kay-Uwe Kasemir
- Navigate by Date:
- Prev:
Re: 3.15 C++ Exception classes Andrew Johnson
- Next:
Re: 3.15 C++ Exception classes Benjamin Franksen
- Index:
2002
2003
2004
2005
<2006>
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
- Navigate by Thread:
- Prev:
Re: 3.15 C++ Exception classes Kay-Uwe Kasemir
- Next:
Re: 3.15 C++ Exception classes Kay-Uwe Kasemir
- Index:
2002
2003
2004
2005
<2006>
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
|