Puzzle: make new compilers understand what g++ 2.95.3 compiled

Discussion in 'C++' started by nospam_news@wanano.net, May 8, 2007.

  1. Guest

    When language changes make old code uncompilable, that's not what is
    called protection of investment.

    New compilers (g++ > 3.2.3) reject classes where methods throw the
    class they belong to.
    gcc 2.95.3 allowed it.

    What are the minimal modification, that leave the usage of the class
    sound and can be compiled by newer compilers.

    Thank you

    ( compile the following code with s.th. like g++ -g -o Exception
    Exception.cpp -lstlport_gcc )

    #include "iostream"

    class Exception {
    public:
    Exception(int);
    void setErrNo(int i) throw(Exception);
    int errNo;

    };

    Exception::Exception(int e) {
    errNo=e;

    }

    void Exception::setErrNo(int i) throw(Exception) {
    auto Exception methodException(2);
    errNo=i;
    throw(methodException);

    };

    int main(char argc, char *argv[], char *env[]) {
    try {
    auto Exception mainException(1);
    mainException.setErrNo(42);
    } catch (Exception caughtException) {
    std::cout << "caught caughtException:" << caughtException.errNo <<
    std::endl;
    }
     
    , May 8, 2007
    #1
    1. Advertising

  2. On May 8, 1:09 pm, ""
    <> wrote:
    > When language changes make old code uncompilable, that's not what is
    > called protection of investment.
    >
    > New compilers (g++ > 3.2.3) reject classes where methods throw the
    > class they belong to.
    > gcc 2.95.3 allowed it.
    >
    > What are the minimal modification, that leave the usage of the class
    > sound and can be compiled by newer compilers.
    >
    > Thank you
    >
    > ( compile the following code with s.th. like g++ -g -o Exception
    > Exception.cpp -lstlport_gcc )
    >
    > #include "iostream"
    >
    > class Exception {
    > public:
    > Exception(int);
    > void setErrNo(int i) throw(Exception);
    > int errNo;
    >
    > };
    >
    > Exception::Exception(int e) {
    > errNo=e;
    >
    > }
    >
    > void Exception::setErrNo(int i) throw(Exception) {
    > auto Exception methodException(2);
    > errNo=i;
    > throw(methodException);
    >
    > };
    >
    > int main(char argc, char *argv[], char *env[]) {
    > try {
    > auto Exception mainException(1);
    > mainException.setErrNo(42);
    > } catch (Exception caughtException) {
    > std::cout << "caught caughtException:" << caughtException.errNo <<
    > std::endl;
    >
    > }


    Remove the `throw(Exception)' statements from the function setErrNo.
    Your catch block is trying to catch an exceptions of type Exception
    and setErrNo will throw and Exception type so it will be caught
    correctly.

    Using gcc 3.4.6 it will compile and work fine this way.

    The C++ standard states that "Classes in exception specifiers must be
    complete types", so throw(Exception) is disallowed.
     
    Keith Halligan, May 8, 2007
    #2
    1. Advertising

  3. Guest

    Solution for: throwing exception classes explicitly

    Thank you Keith Halligan.

    To keep the information in the signatures, we now use an empty
    declarative substitute, so the developer can see from the header, what
    he might have to catch.

    #include "iostream"

    #if ( GCC_VERSION > 30000 )
    # define declare_throw(Exception) throw(Exception)
    #else
    # define declare_throw(Exception)
    #endif

    class Exception {
    public:
    Exception(int);
    void setErrNo(int i) declare_throw(Exception);
    int errNo;
    };

    Exception::Exception(int e) {
    errNo=e;
    }

    void Exception::setErrNo(int i) declare_throw(Exception) {
    auto Exception methodException(2);
    errNo=i;
    throw(methodException);
    };

    int main(char argc, char *argv[], char *env[]) {
    try {
    auto Exception mainException(1);
    mainException.setErrNo(42);
    } catch (Exception caughtException) {
    std::cout << "caught caughtException:" << caughtException.errNo <<
    std::endl;
    }
    }
     
    , May 8, 2007
    #3
  4. Fei Liu Guest

    Re: Solution for: throwing exception classes explicitly

    wrote:
    > Thank you Keith Halligan.
    >
    > To keep the information in the signatures, we now use an empty
    > declarative substitute, so the developer can see from the header, what
    > he might have to catch.
    >
    > #include "iostream"
    >
    > #if ( GCC_VERSION > 30000 )
    > # define declare_throw(Exception) throw(Exception)
    > #else
    > # define declare_throw(Exception)
    > #endif
    >
    > class Exception {
    > public:
    > Exception(int);
    > void setErrNo(int i) declare_throw(Exception);
    > int errNo;
    > };
    >
    > Exception::Exception(int e) {
    > errNo=e;
    > }
    >
    > void Exception::setErrNo(int i) declare_throw(Exception) {
    > auto Exception methodException(2);
    > errNo=i;
    > throw(methodException);
    > };
    >
    > int main(char argc, char *argv[], char *env[]) {
    > try {
    > auto Exception mainException(1);
    > mainException.setErrNo(42);
    > } catch (Exception caughtException) {
    > std::cout << "caught caughtException:" << caughtException.errNo <<
    > std::endl;
    > }
    > }
    >


    This is a good practical solution. Did you try throw(Exception *)? Or is
    that something not allowed in C++? I belive you can throw string,
    integer etc. So you could throw a string message as well.
     
    Fei Liu, May 8, 2007
    #4
  5. Andre Kostur Guest

    Re: Solution for: throwing exception classes explicitly

    Fei Liu <> wrote in news:f1qe4h$o2h$:

    > wrote:
    >> Thank you Keith Halligan.
    >>
    >> To keep the information in the signatures, we now use an empty
    >> declarative substitute, so the developer can see from the header, what
    >> he might have to catch.
    >>
    >> #include "iostream"
    >>
    >> #if ( GCC_VERSION > 30000 )
    >> # define declare_throw(Exception) throw(Exception)
    >> #else
    >> # define declare_throw(Exception)
    >> #endif
    >>
    >> class Exception {
    >> public:
    >> Exception(int);
    >> void setErrNo(int i) declare_throw(Exception);
    >> int errNo;
    >> };
    >>
    >> Exception::Exception(int e) {
    >> errNo=e;
    >> }
    >>
    >> void Exception::setErrNo(int i) declare_throw(Exception) {
    >> auto Exception methodException(2);
    >> errNo=i;
    >> throw(methodException);
    >> };
    >>
    >> int main(char argc, char *argv[], char *env[]) {
    >> try {
    >> auto Exception mainException(1);
    >> mainException.setErrNo(42);
    >> } catch (Exception caughtException) {
    >> std::cout << "caught caughtException:" << caughtException.errNo <<
    >> std::endl;
    >> }
    >> }
    >>

    >
    > This is a good practical solution. Did you try throw(Exception *)? Or

    is
    > that something not allowed in C++? I belive you can throw string,
    > integer etc. So you could throw a string message as well.
    >


    Be careful when throwing pointers as exceptions. Specifically, what is
    the pointer going to be pointing at by the time the catch clause is
    evaluated. If you've thrown a pointer to a local variable, it will be
    out of scope by the time the catch clause executes.
     
    Andre Kostur, May 8, 2007
    #5
  6. peter koch Guest

    Re: Solution for: throwing exception classes explicitly

    On 8 Maj, 16:41, ""
    <> wrote:
    > Thank you Keith Halligan.
    >
    > To keep the information in the signatures, we now use an empty
    > declarative substitute, so the developer can see from the header, what
    > he might have to catch.


    I recommend a much better solution: do not use exception
    specifications. Instead have the specification in a comment:
    void setErrNo(int i); // throws Exception
    Exception specifications really are more of less useless and will
    often make the code slower and (more important) difficult to maintain/
    extend. The comment is harmless here.
    I assume that you do not expect the immediate caller to catch the
    exception? In that case, using return codes would seem like a better
    idea.
    Last, I do not understand that usage of "auto". What is it for? The
    keyword is clearly superflous here.

    /Peter
    >
    > #include "iostream"
    >
    > #if ( GCC_VERSION > 30000 )
    > # define declare_throw(Exception) throw(Exception)
    > #else
    > # define declare_throw(Exception)
    > #endif
    >
    > class Exception {
    > public:
    > Exception(int);
    > void setErrNo(int i) declare_throw(Exception);
    > int errNo;
    >
    > };
    >
    > Exception::Exception(int e) {
    > errNo=e;
    >
    > }
    >
    > void Exception::setErrNo(int i) declare_throw(Exception) {
    > auto Exception methodException(2);
    > errNo=i;
    > throw(methodException);
    >
    > };
    >
    > int main(char argc, char *argv[], char *env[]) {
    > try {
    > auto Exception mainException(1);
    > mainException.setErrNo(42);
    > } catch (Exception caughtException) {
    > std::cout << "caught caughtException:" << caughtException.errNo <<
    > std::endl;
    > }
    >
    >
    >
    > }
     
    peter koch, May 8, 2007
    #6
    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. Klaus Schneider
    Replies:
    1
    Views:
    582
    Rolf Magnus
    Dec 2, 2004
  2. geletine

    commercial c compilers vs free c compilers

    geletine, Jul 2, 2006, in forum: C Programming
    Replies:
    33
    Views:
    1,364
  3. Replies:
    2
    Views:
    291
  4. lander
    Replies:
    5
    Views:
    625
    bruce barker
    Mar 5, 2008
  5. Juha Nieminen
    Replies:
    3
    Views:
    368
    Stuart
    Sep 21, 2012
Loading...

Share This Page