EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

2002  2003  2004  2005  <20062007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024  Index 2002  2003  2004  2005  <20062007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: Re: 3.15 C++ Exception classes
From: Andrew Johnson <[email protected]>
To: Core talk list <[email protected]>
Date: Tue, 21 Feb 2006 17:54:40 -0600
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  <20062007  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  <20062007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
ANJ, 02 Feb 2012 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·