f



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

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;
}

0
5/8/2007 12:09:27 PM
comp.lang.c++ 49423 articles. 6 followers. Post Follow

5 Replies
626 Views

Similar Articles

[PageSpeed] 35

On May 8, 1:09 pm, "nospam_n...@wanano.net"
<Torsten.Reich...@wanano.net> 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.


0
5/8/2007 12:40:03 PM
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;
  }
}

0
5/8/2007 2:41:45 PM
nospam_news@wanano.net 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.
0
feiliu (123)
5/8/2007 6:05:16 PM
Fei Liu <feiliu@aepnetworks.com> wrote in news:f1qe4h$o2h$1@aioe.org:

> nospam_news@wanano.net 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.

0
nntpspam (752)
5/8/2007 7:04:43 PM
On 8 Maj, 16:41, "nospam_n...@wanano.net"
<Torsten.Reich...@wanano.net> 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;
>   }
>
>
>
> }

0
5/8/2007 9:39:17 PM
Reply: