[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c++

asserting nothings thrown in a destructor

g3rc4n@gmail.com

12/11/2008 1:23:00 AM

i know that macros shouldn't be used in c++ unnecessarily because of
scope rules, but what if i put something like this in destructor's
where i don't know if T will throw something, as macros will also make
it clear to the reader what I'm trying to achieve

if i put T in an std::auto_ptr i can't assert nothing is thrown

#define ON_SOMETHING_THROWN ::abort();
#define START_ASSERT_NOTHING_THROWN try{
#define END_ASSERT_NOTHING_THROWN } catch(...){ ON_SOMETHING_THROWN }

template<typename T>
class foo{
public:
foo():
ptr(new T()){
}
~foo(){
START_ASSERT_NOTHING_THROWN

delete ptr;

END_ASSERT_NOTHING_THROWN
}
private:
T* ptr;
};
6 Answers

olekk

12/11/2008 8:28:00 AM

0



g3rc4n@gmail.com wrote:
> i know that macros shouldn't be used in c++ unnecessarily because of
> scope rules, but what if i put something like this in destructor's
> where i don't know if T will throw something, as macros will also make
> it clear to the reader what I'm trying to achieve
>
> if i put T in an std::auto_ptr i can't assert nothing is thrown
>
> #define ON_SOMETHING_THROWN > ::abort();
> #define START_ASSERT_NOTHING_THROWN > try{
> #define END_ASSERT_NOTHING_THROWN > } > catch(...){ > ON_SOMETHING_THROWN > }
>
> template<typename T>
> class foo{
> public:
> foo():
> ptr(new T()){
> }
> ~foo(){
> START_ASSERT_NOTHING_THROWN
>
> delete ptr;
>
> END_ASSERT_NOTHING_THROWN
> }
> private:
> T* ptr;
> };

So what's the question?

Rolf Magnus

12/11/2008 9:11:00 AM

0

g3rc4n@gmail.com wrote:

> i know that macros shouldn't be used in c++ unnecessarily because of
> scope rules, but what if i put something like this in destructor's
> where i don't know if T will throw something, as macros will also make
> it clear to the reader what I'm trying to achieve
>
> if i put T in an std::auto_ptr i can't assert nothing is thrown
>
> #define ON_SOMETHING_THROWN > ::abort();
> #define START_ASSERT_NOTHING_THROWN > try{
> #define END_ASSERT_NOTHING_THROWN > } > catch(...){ > ON_SOMETHING_THROWN > }
>
> template<typename T>
> class foo{
> public:
> foo():
> ptr(new T()){
> }
> ~foo(){
> START_ASSERT_NOTHING_THROWN
>
> delete ptr;
>
> END_ASSERT_NOTHING_THROWN
> }
> private:
> T* ptr;
> };

That isn't necessariy altogether. If an exception is not caught anywhere,
std::unexpected() is called, for which you can define your own handler. By
default, it calls std::terminate, which by default calls abort.

g3rc4n@gmail.com

12/11/2008 1:32:00 PM

0

On Dec 11, 9:10 am, Rolf Magnus <ramag...@t-online.de> wrote:
> g3r...@gmail.com wrote:
> > i know that macros shouldn't be used in c++ unnecessarily because of
> > scope rules, but what if i put something like this in destructor's
> > where i don't know if T will throw something, as macros will also make
> > it clear to the reader what I'm trying to achieve
>
> > if i put T in an std::auto_ptr i can't assert nothing is thrown
>
> > #define ON_SOMETHING_THROWN > > ::abort();
> > #define START_ASSERT_NOTHING_THROWN > > try{
> > #define END_ASSERT_NOTHING_THROWN > > } > > catch(...){ > > ON_SOMETHING_THROWN > > }
>
> > template<typename T>
> > class foo{
> > public:
> > foo():
> > ptr(new T()){
> > }
> > ~foo(){
> > START_ASSERT_NOTHING_THROWN
>
> > delete ptr;
>
> > END_ASSERT_NOTHING_THROWN
> > }
> > private:
> > T* ptr;
> > };
>
> That isn't necessariy altogether. If an exception is not caught anywhere,
> std::unexpected() is called, for which you can define your own handler. By
> default, it calls std::terminate, which by default calls abort.

yeah but i can assert nothing is thrown this way?

gpderetta

12/11/2008 2:24:00 PM

0

On Dec 11, 2:32 pm, "g3r...@gmail.com" <g3r...@gmail.com> wrote:
> On Dec 11, 9:10 am, Rolf Magnus <ramag...@t-online.de> wrote:
>
>
>
> > g3r...@gmail.com wrote:
> > > i know that macros shouldn't be used in c++ unnecessarily because of
> > > scope rules, but what if i put something like this in destructor's
> > > where i don't know if T will throw something, as macros will also make
> > > it clear to the reader what I'm trying to achieve
>
> > > if i put T in an std::auto_ptr i can't assert nothing is thrown
>
> > > #define ON_SOMETHING_THROWN > > > ::abort();
> > > #define START_ASSERT_NOTHING_THROWN > > > try{
> > > #define END_ASSERT_NOTHING_THROWN > > > } > > > catch(...){ > > > ON_SOMETHING_THROWN > > > }
>
> > > template<typename T>
> > > class foo{
> > > public:
> > > foo():
> > > ptr(new T()){
> > > }
> > > ~foo(){
> > > START_ASSERT_NOTHING_THROWN
>
> > > delete ptr;
>
> > > END_ASSERT_NOTHING_THROWN
> > > }
> > > private:
> > > T* ptr;
> > > };
>
> > That isn't necessariy altogether. If an exception is not caught anywhere,
> > std::unexpected() is called, for which you can define your own handler. By
> > default, it calls std::terminate, which by default calls abort.
>
> yeah but i can assert nothing is thrown this way?

Macros are often evil, but macros that expand to unmatched parenthesis
are, IMHO, even worse.
What's wrong with :

~foo() throw() {
// code that should not throw here
}

--
Giovanni P. Deretta

jason.cipriani@gmail.com

12/12/2008 1:27:00 AM

0

On Dec 11, 9:24 am, gpderetta <gpdere...@gmail.com> wrote:
> On Dec 11, 2:32 pm, "g3r...@gmail.com" <g3r...@gmail.com> wrote:
>
>
>
> > On Dec 11, 9:10 am, Rolf Magnus <ramag...@t-online.de> wrote:
>
> > > g3r...@gmail.com wrote:
> > > > i know that macros shouldn't be used in c++ unnecessarily because of
> > > > scope rules, but what if i put something like this in destructor's
> > > > where i don't know if T will throw something, as macros will also make
> > > > it clear to the reader what I'm trying to achieve
>
> > > > if i put T in an std::auto_ptr i can't assert nothing is thrown
>
> > > > #define ON_SOMETHING_THROWN > > > > ::abort();
> > > > #define START_ASSERT_NOTHING_THROWN > > > > try{
> > > > #define END_ASSERT_NOTHING_THROWN > > > > } > > > > catch(...){ > > > > ON_SOMETHING_THROWN > > > > }
>
> > > > template<typename T>
> > > > class foo{
> > > > public:
> > > > foo():
> > > > ptr(new T()){
> > > > }
> > > > ~foo(){
> > > > START_ASSERT_NOTHING_THROWN
>
> > > > delete ptr;
>
> > > > END_ASSERT_NOTHING_THROWN
> > > > }
> > > > private:
> > > > T* ptr;
> > > > };
>
> > > That isn't necessariy altogether. If an exception is not caught anywhere,
> > > std::unexpected() is called, for which you can define your own handler. By
> > > default, it calls std::terminate, which by default calls abort.
>
> > yeah but i can assert nothing is thrown this way?
>
> Macros are often evil, but macros that expand to unmatched parenthesis
> are, IMHO, even worse.
> What's wrong with :
>
> ~foo()  throw() {
>   // code that should not throw here
>
> }


Well, this isn't necessarily a good reason, but the MS compiler
ignores throw specifiers entirely, so code like this:


#include <iostream>
using namespace std;

void throw_something () { throw 42; }

class A {
public:
~A () throw () { throw_something(); }
};

int main () {
try {
delete new A;
} catch (...) {
cout << "caught, not aborted." << endl;
}
}


When compiled with MSVC, prints "caught, not aborted", but when
compiled with MinGW GCC, it aborts. So if you're using the MS
compiler, you could argue that it's valid to check just to avoid
problems on other compilers. On the other hand, if things that you're
doing in your constructor are throwing exceptions, and you aren't
sure, that might be a sign of a bigger design flaw. E.g. if you're
going to do something that might throw an exception in a destructor,
perhaps consider this instead:


foo::~foo () throw () {

try {
something_that_runs_the_risk_of_throwing();
} catch (...) {
recover_and_continue_destroying_this();
}

}


Jason

g3rc4n@gmail.com

12/13/2008 4:22:00 PM

0

On Dec 12, 1:26 am, "jason.cipri...@gmail.com"
<jason.cipri...@gmail.com> wrote:
> On Dec 11, 9:24 am, gpderetta <gpdere...@gmail.com> wrote:
>
>
>
> > On Dec 11, 2:32 pm, "g3r...@gmail.com" <g3r...@gmail.com> wrote:
>
> > > On Dec 11, 9:10 am, Rolf Magnus <ramag...@t-online.de> wrote:
>
> > > > g3r...@gmail.com wrote:
> > > > > i know that macros shouldn't be used in c++ unnecessarily because of
> > > > > scope rules, but what if i put something like this in destructor's
> > > > > where i don't know if T will throw something, as macros will also make
> > > > > it clear to the reader what I'm trying to achieve
>
> > > > > if i put T in an std::auto_ptr i can't assert nothing is thrown
>
> > > > > #define ON_SOMETHING_THROWN > > > > > ::abort();
> > > > > #define START_ASSERT_NOTHING_THROWN > > > > > try{
> > > > > #define END_ASSERT_NOTHING_THROWN > > > > > } > > > > > catch(...){ > > > > > ON_SOMETHING_THROWN > > > > > }
>
> > > > > template<typename T>
> > > > > class foo{
> > > > > public:
> > > > > foo():
> > > > > ptr(new T()){
> > > > > }
> > > > > ~foo(){
> > > > > START_ASSERT_NOTHING_THROWN
>
> > > > > delete ptr;
>
> > > > > END_ASSERT_NOTHING_THROWN
> > > > > }
> > > > > private:
> > > > > T* ptr;
> > > > > };
>
> > > > That isn't necessariy altogether. If an exception is not caught anywhere,
> > > > std::unexpected() is called, for which you can define your own handler. By
> > > > default, it calls std::terminate, which by default calls abort.
>
> > > yeah but i can assert nothing is thrown this way?
>
> > Macros are often evil, but macros that expand to unmatched parenthesis
> > are, IMHO, even worse.
> > What's wrong with :
>
> > ~foo()  throw() {
> >   // code that should not throw here
>
> > }
>
> Well, this isn't necessarily a good reason, but the MS compiler
> ignores throw specifiers entirely, so code like this:
>
> #include <iostream>
> using namespace std;
>
> void throw_something () { throw 42; }
>
> class A {
> public:
>   ~A () throw () { throw_something(); }
>
> };
>
> int main () {
>   try {
>     delete new A;
>   } catch (...) {
>     cout << "caught, not aborted." << endl;
>   }
>
> }
>
> When compiled with MSVC, prints "caught, not aborted", but when
> compiled with MinGW GCC, it aborts. So if you're using the MS
> compiler, you could argue that it's valid to check just to avoid
> problems on other compilers. On the other hand, if things that you're
> doing in your constructor are throwing exceptions, and you aren't
> sure, that might be a sign of a bigger design flaw. E.g. if you're
> going to do something that might throw an exception in a destructor,
> perhaps consider this instead:
>
> foo::~foo () throw () {
>
>   try {
>     something_that_runs_the_risk_of_throwing();
>   } catch (...) {
>     recover_and_continue_destroying_this();
>   }
>
> }
>
> Jason

ok thanks