asserting nothings thrown in a destructor

Discussion in 'C++' started by g3rc4n@gmail.com, Dec 11, 2008.

  1. Guest

    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;
    };
    , Dec 11, 2008
    #1
    1. Advertising

  2. olekk Guest

    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?
    olekk, Dec 11, 2008
    #2
    1. Advertising

  3. Rolf Magnus Guest

    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.
    Rolf Magnus, Dec 11, 2008
    #3
  4. Guest

    On Dec 11, 9:10 am, Rolf Magnus <> wrote:
    > 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?
    , Dec 11, 2008
    #4
  5. gpderetta Guest

    On Dec 11, 2:32 pm, "" <> wrote:
    > On Dec 11, 9:10 am, Rolf Magnus <> wrote:
    >
    >
    >
    > > 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
    gpderetta, Dec 11, 2008
    #5
  6. Guest

    On Dec 11, 9:24 am, gpderetta <> wrote:
    > On Dec 11, 2:32 pm, "" <> wrote:
    >
    >
    >
    > > On Dec 11, 9:10 am, Rolf Magnus <> wrote:

    >
    > > > 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
    , Dec 12, 2008
    #6
  7. Guest

    On Dec 12, 1:26 am, ""
    <> wrote:
    > On Dec 11, 9:24 am, gpderetta <> wrote:
    >
    >
    >
    > > On Dec 11, 2:32 pm, "" <> wrote:

    >
    > > > On Dec 11, 9:10 am, Rolf Magnus <> wrote:

    >
    > > > > 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
    , Dec 13, 2008
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    2
    Views:
    357
  2. Replies:
    0
    Views:
    625
  3. paswenson

    Asserting IRQs

    paswenson, Jan 23, 2008, in forum: VHDL
    Replies:
    0
    Views:
    554
    paswenson
    Jan 23, 2008
  4. David Brady
    Replies:
    2
    Views:
    153
    Austin Ziegler
    Aug 26, 2005
  5. Esad Hajdarevic

    asserting in code vs unit tests

    Esad Hajdarevic, Mar 5, 2006, in forum: Ruby
    Replies:
    12
    Views:
    217
    chiaro scuro
    Mar 6, 2006
Loading...

Share This Page