← Back to team overview

dolfin team mailing list archive

Re: GenericTensor::down_cast() should throw std::bad_cast instead of invoking dolfin::error

 

On Wed, 2010-08-04 at 11:18 +0200, Florian Rathgeber wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> On 03.08.2010 21:21, Anders Logg wrote:
> > On Tue, Aug 03, 2010 at 06:19:16PM +0100, Garth N. Wells wrote:
> >> On Tue, 2010-08-03 at 19:14 +0200, Anders Logg wrote:
> >>> On Tue, Aug 03, 2010 at 03:41:35PM +0100, Garth N. Wells wrote:
> >>>> On Tue, 2010-08-03 at 07:51 +0200, Florian Rathgeber wrote:
> >>>>> -----BEGIN PGP SIGNED MESSAGE-----
> >>>>> Hash: SHA1
> >>>>>
> >>>>> On 02.08.2010 18:50, Garth N. Wells wrote:
> >>>>>> On Mon, 2010-08-02 at 10:33 +0200, Anders Logg wrote:
> >>>>>>> On Sun, Aug 01, 2010 at 06:35:22PM +0100, Garth N. Wells wrote:
> >>>>>>>> On Sun, 2010-08-01 at 12:40 +0200, Florian Rathgeber wrote:
> >>>>>>>>> -----BEGIN PGP SIGNED MESSAGE-----
> >>>>>>>>> Hash: SHA1
> >>>>>>>>>
> >>>>>>>>> Hi,
> >>>>>>>>>
> >>>>>>>>> When using GenericTensor::down_cast() for a tentative down cast it would
> >>>>>>>>> be helpful if it would throw std::bad_alloc (as any dynamic_cast would
> >>>>>>>>> do)
> >>>>>>>>
> >>>>>>>> Do you mean std::bad_cast?
> >>>>>>>>
> >>>>>>>>> instead of invoking dolfin::error. Currently you would have to catch
> >>>>>>>>> std::runtime_error and check what() to distinguish a failed cast from
> >>>>>>>>> another dolfin::error, which is pretty inconvenient. Is there a specific
> >>>>>>>>> reason why it is implemented this way?
> >>>>>>>>>
> >>>>>>>>
> >>>>>>>> Not really.
> >>>>>>>>
> >>>>>>>> It's not too clear to me what you'd like. Would you prefer that
> >>>>>>>> down_cast doesn't throw an error, but leave it up to the programmer to
> >>>>>>>> check that a cast was successful, or just that DOLFIN catch a
> >>>>>>>> std::bad_cast and print more information before throwing an error?
> >>>>>>>
> >>>>>>> I think the best would be if DOLFIN caught the error, then wrote an
> >>>>>>> informative message (since it knows exactly what went wrong) and then
> >>>>>>> threw bad_cast.
> >>>>>>>
> >>>>>>
> >>>>>> Looks like there isn't much that can be done - std::bad_cast is only
> >>>>>> thrown when casting references, not pointers (as we do internally). From
> >>>>>> what I've read, our way of checking for a null pointer is correct.
> >>>>>
> >>>>> If down_cast() were implemented as casting the reference directly,
> >>>>> dynamic_cast would throw std::bad_cast if it fails.
> >>>>>
> >>>>> The check for the null pointer is correct, my point is that in this case
> >>>>> not a std::runtime_error should be thrown (which happens by calling
> >>>>> dolfin::error), but instead the message should be printed e.g. by
> >>>>> dolfin::warning and then a std::bad_cast thrown. That was Anders'
> >>>>> suggestion if I got that right.
> >>>>>
> >>>>> In that way down_cast() could be used as a tentative cast which is not
> >>>>> really possible if it throws the same exception that could be caused by
> >>>>> and DOLFIN error.
> >>>>>
> >>>>
> >>>> GenericTensor::down_cast now catches an exception and then throws an
> >>>> error. It was simpler than I thought because return statements can be
> >>>> used inside a try block (which I didn't know).
> >>>>
> >>>> Garth
> >>>
> >>> Does this work as intended? It still looks like we catch the exception
> >>> and let then throw a runtime error by calling error():
> >>>
> >>>  catch (std::exception& e)
> >>>  {
> >>>    error("GenericTensor cannot be cast to the requested type: %s", e.what());
> >>>  }
> >>>
> >>
> >> Yes. What else do we want to do other than eventually throw an error? We
> >> don't want to carry on with a bad cast. If a programmer wants to do
> >> something fancy when a cast fails, they can use dynamic_cast directly
> >> and catch an exception.
> >>
> >> Garth
> > 
> > I thought the idea was to throw a more specific exception since we
> > know exactly what type of exception it is. We throw away that
> > information when we just call error. Maybe the error() function should
> > take the exception as an argument so that it can throw that exception
> > instead of just runtime_error?
> > 
> > --
> > Anders
> 
> I agree with Anders. Calling error doesn't give the user the possibility
> to _only_ catch a dynamic_cast exception through catching std::bad_cast.
> She would still have to catch std::runtime_error and figure out what
> actually happened.
> 

If that's desired, then just use dynamic_cast and catch the exception.
It's simpler than having a GenericTensor member function do it.
GenericTensor::down_cast is a convenience function and the priority is
that it is safe.

Garth



> Florian
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v2.0.12 (MingW32)
> 
> iEYEARECAAYFAkxZMFMACgkQ8Z6llsctAxYmBwCffUojduSyHrtGAr4dtF8qn/5C
> bOAAoNjiPEnmyDmXSVO2rtwrbOefCNfZ
> =fDB0
> -----END PGP SIGNATURE-----
> 





Follow ups

References