[geos-devel] GEOSException is incompatible with std::exception

strk at refractions.net strk at refractions.net
Tue Apr 4 03:08:59 EDT 2006


Good catch Mateus, anyway there's no std::exception(const char*)
interface in my STL implementation (GCC 3.3).

Here it is:

  /**
   *  @brief Base class for all library exceptions.
   *
   *  This is the base class for all exceptions thrown by the standard
   *  library, and by certain language expressions.  You are free to derive
   *  your own %exception classes, or use a different hierarchy, or to
   *  throw non-class data (e.g., fundamental types).
   */
  class exception
  {
  public:
    exception() throw() { }
    virtual ~exception() throw();
    /** Returns a C-style character string describing the general cause
     *  of the current error.  */
    virtual const char* what() const throw();
  };

We can pick one of the derivated classes like runtime_exception
insted. That one allows contruction taking 'const string&'.
It's defined in <stdexcept>.
What do you think ?

--strk;
 
On Tue, Apr 04, 2006 at 12:09:59AM +0200, Mateusz Å?oskot wrote:
> Hi,
> 
> GEOSException class and all its derivatives is incompatible with
> std::exception.
> GEOSException is derived from std::exception but it does not make much
> sense. It even introduces many confusions.
> 
> GEOSException has its own member to store message GEOSException::txt.
> But std::exception has it's own member storing exception message.
> It also has it's own version of what() function that returns
> GEOSException::txt but this what() has nothing to do with that one
> provided by std::exception.
> 
> The main problem is that exception details are not available through
> std::exception interface.
> Simply, this structure is a kind of two types in one, but every of this
> participator is completely separated from another one.
> 
> Here is illustration of the problem:
> 
> try
> {
>    throw geos::util::GEOSException("This is a message from GEOS.");
> }
> catch (std::exception const& e)
> {
>    std::string msg = e.what();
>    std::cout << msg << std::endl; <--- BUM! BUM! BUM!
> }
> 
> In the example above, exceptions are catched through base
> std::exception. It's very common situation.
> The problem is that e.what() returns null pointer.
> std::exception member of string message is not initialized during
> construction of GEOSException. This is a bug.
> 
> This example illustrates that deriving GEOSException from std::exception
> has no effect at all. std::exception type is completely unused.
> 
> My suggestions are:
> 1. To remove GEOSException::txt
> 
> 2. To use std::exception buffer member for message (in VC++ version of
> STL it's private member std::exception::_m_what declared as:
> const char *_m_what;
> 
> 3. To initialize call base class (std::exception) constructor during
> construction of GEOSException using initializers list:
> 
> class GEOSException : public std::exception
> {
> public:
>    GEOSException(char const* msg) : std::exception(msg) {}
>    GEOSException(std::string const& msg)
>       : std::exception(msg.c_str())
>    {}
>    virtual ~GEOSException() {}
> };
> 
> 4. Use initializers list in every class derived from GEOSException,
> so every time std::exception's message member will be initialized.
> 
> Here is usage example that proofs it fixes the problem I introduced:
> 
> ///////////////////////////////////////////////////////////
> #include <iostream>
> #include <string>
> #include <exception>
> 
> class GEOSException : public std::exception
> {
> public:
>    GEOSException(char const* msg) : std::exception(msg) {}
>    GEOSException(std::string const& msg)
>       : std::exception(msg.c_str())
>    {}
>    virtual ~GEOSException() {}
> };
> 
> int main()
> {
>    try
>    {
>       throw GEOSException("This is a message from GEOS.");
>    }
>    catch (std::exception const& e)
>    {
>       std::string msg = e.what();
>       std::cout << msg << std::endl;
>    }
> 
>    try
>    {
>       std::string msg("This is a std::string message from GEOS.");
>       throw GEOSException(msg);
>    }
>    catch (std::exception const& e)
>    {
>       std::string msg = e.what();
>       std::cout << msg << std::endl;
>    }
> 
>    return 0;
> }
> ///////////////////////////////////////////////////////////
> 
> 
> Cheers
> -- 
> Mateusz Łoskot
> http://mateusz.loskot.net
> 
> _______________________________________________
> geos-devel mailing list
> geos-devel at geos.refractions.net
> http://geos.refractions.net/mailman/listinfo/geos-devel

-- 

 /"\    ASCII Ribbon Campaign
 \ /    Respect for low technology.
  X     Keep e-mail messages readable by any computer system.
 / \    Keep it ASCII. 




More information about the geos-devel mailing list