-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 To round up the discussion: I wasn't aware of GenericTensor::has_type(). I think that is the more "correct" way of doing what I want, i.e. instead of casting and catching the exception or doing a tentative dynamic_cast and checking for a null pointer one should check through has_type() if the down_cast is safe.
As an aside, using dynamic_cast always return a null pointer in my case even though the down_cast would succeed. I couldn't really figure out what was the reason for that, but above method using has_type() works fine. Florian On 04.08.2010 12:47, Florian Rathgeber wrote: > On 04.08.2010 11:22, Garth N. Wells wrote: >> On Wed, 2010-08-04 at 11:18 +0200, Florian Rathgeber wrote: >> 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 > > I used GenericTensor::down_cast since it was convenient. But I > understand that it's desirable to only have one kind of exception in > terms of general library design. I can live with using a dynamic_cast > for that purpose, just wanted to bring up the issue and hear your > opinions on it > > Florian -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.12 (MingW32) iEYEARECAAYFAkxcGT0ACgkQ8Z6llsctAxYd7wCaA/2c4101U5sH8z6alwiQ3gcJ XnIAn1pV45ulIqHzCyq76B3+gKldEEsT =Xe18 -----END PGP SIGNATURE-----
smime.p7s
Description: S/MIME Cryptographic Signature
_______________________________________________ Mailing list: https://launchpad.net/~dolfin Post to : dolfin@lists.launchpad.net Unsubscribe : https://launchpad.net/~dolfin More help : https://help.launchpad.net/ListHelp