C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Troubles with exception::what()

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++)
View previous topic :: View next topic  
Author Message
Dario
Guest





PostPosted: Wed Sep 24, 2003 7:41 am    Post subject: Troubles with exception::what() Reply with quote



The following simple program behaves differently
in Windows and Linux .

#include <stdexcept>
#include <iostream>
#include <string>
using namespace std;
class LogicError : public logic_error {
public:
string desc;
explicit LogicError(string desc)
: logic_error("parent description"), desc(desc) {
}
virtual const char * what() const throw() {
return desc.c_str();
}
};
void f() {
throw LogicError("child description");
}
int main() {
try {
f();
} catch(exception e) {
cout << "e.what=[" << e.what() << "]" << endl;
}
try {
f();
} catch(exception & e) {
cout << "e.what=[" << e.what() << "]" << endl;
}
return 0;
}

When I run it on Windows (Visual Studio 6.0) I obtain:
e.what=[]
e.what=[child description]

When I run it on Windows (Visual Studio 7.1) I obtain:
e.what=[Unknown exception]
e.what=[child description]

On Linux I (obtain:
e.what=[9exception]
e.what=[child description]

Two questions to the C++ gurus:
<1> Which is the expected ANSI-C++ behaviour?
<2> Why. in each run, the first output row
is different from the second one?

Thanks for the help.

- Dario

Back to top
Dario
Guest





PostPosted: Thu Sep 25, 2003 5:51 pm    Post subject: Re: Troubles with exception::what() Reply with quote




Quote:
The following simple program behaves differently
in Windows and Linux .

#include <stdexcept
#include #include using namespace std;
class LogicError : public logic_error {
public:
string desc;
explicit LogicError(string desc)
: logic_error("parent description"), desc(desc) {
}
virtual const char * what() const throw() {
return desc.c_str();
}
};
void f() {
throw LogicError("child description");
}
int main() {
try {
f();
} catch(exception e) {
cout << "e.what=[" << e.what() << "]" << endl;
}
try {
f();
} catch(exception & e) {
cout << "e.what=[" << e.what() << "]" << endl;
}
return 0;
}

When I run it on Windows (Visual Studio 6.0) I obtain:
e.what=[]
e.what=[child description]

When I run it on Windows (Visual Studio 7.1) I obtain:
e.what=[Unknown exception]
e.what=[child description]

On Linux I (obtain:
e.what=[9exception]
e.what=[child description]

Two questions to the C++ gurus:
1> Which is the expected ANSI-C++ behaviour?
2> Why. in each run, the first output row
is different from the second one?

Thanks for the help.

- Dario

No-one is able to give me an help ?

- Dario


Back to top
Gianni Mariani
Guest





PostPosted: Fri Sep 26, 2003 4:47 am    Post subject: Re: Troubles with exception::what() Reply with quote



Dario wrote:
Quote:
The following simple program behaves differently
in Windows and Linux .


#include <stdexcept
#include #include using namespace std;
class LogicError : public logic_error {
public:
string desc;
explicit LogicError(string desc)
: logic_error("parent description"), desc(desc) {
}
virtual const char * what() const throw() {
return desc.c_str();
}

This is overriding the base "what" method.

Incidently, gcc 3.3.1 needed this:

~LogicError() throw() {};

It seems to make sense since the destructor of the base class also
specified throw().

Quote:
};
void f() {
throw LogicError("child description");
}
int main() {
try {
f();
} catch(exception e) {

Exception caught by value - a copy of "exception" is made here.

Well this means that you're not using the method what above.


Quote:
cout << "e.what=[" << e.what() << "]" << endl;
}
try {
f();
} catch(exception & e) {

Exception caught by reference - cool, now you will get the right what
becuase you are actually using a LogicError object and not an
"exception" object copied.

Quote:
cout << "e.what=[" << e.what() << "]" << endl;
}
return 0;
}

When I run it on Windows (Visual Studio 6.0) I obtain:
e.what=[]
e.what=[child description]

When I run it on Windows (Visual Studio 7.1) I obtain:
e.what=[Unknown exception]
e.what=[child description]

On Linux I (obtain:
e.what=[9exception]
e.what=[child description]

Two questions to the C++ gurus:
1> Which is the expected ANSI-C++ behaviour?

All of them. What happens on the first catch is undefined.

Quote:
2> Why. in each run, the first output row
is different from the second one?

Because they are different objects.

Quote:

Thanks for the help.


Back to top
Bob Hairgrove
Guest





PostPosted: Fri Sep 26, 2003 8:21 am    Post subject: Re: Troubles with exception::what() Reply with quote

On 26 Sep 2003 04:47:25 GMT, Gianni Mariani <gi2nospam (AT) mariani (DOT) ws>
wrote:

Quote:
Dario wrote:
The following simple program behaves differently
in Windows and Linux .


#include <stdexcept
#include #include using namespace std;

BTW, one shouldn't ever put "using namespace ... header file... for toy programs such as this, it is probably OK.

Quote:
class LogicError : public logic_error {
public:
string desc;
explicit LogicError(string desc)
: logic_error("parent description"), desc(desc) {
}
virtual const char * what() const throw() {
return desc.c_str();
}

He also should have a *virtual* destructor. It might be a better idea
to derive the class from std::exception and not from one of its
derived classes because not every implementation of the STL uses a
virtual destructor in the derived classes. In some of them, it will
work; in others, maybe not.

Quote:

This is overriding the base "what" method.

Incidently, gcc 3.3.1 needed this:

~LogicError() throw() {};

It seems to make sense since the destructor of the base class also
specified throw().

};
void f() {
throw LogicError("child description");
}
int main() {
try {
f();
} catch(exception e) {

Exception caught by value - a copy of "exception" is made here.

Well this means that you're not using the method what above.


cout << "e.what=[" << e.what() << "]" << endl;
}
try {
f();
} catch(exception & e) {

Exception caught by reference - cool, now you will get the right what
becuase you are actually using a LogicError object and not an
"exception" object copied.

cout << "e.what=[" << e.what() << "]" << endl;
}
return 0;
}

When I run it on Windows (Visual Studio 6.0) I obtain:
e.what=[]
e.what=[child description]

When I run it on Windows (Visual Studio 7.1) I obtain:
e.what=[Unknown exception]
e.what=[child description]

On Linux I (obtain:
e.what=[9exception]
e.what=[child description]

Two questions to the C++ gurus:
1> Which is the expected ANSI-C++ behaviour?

All of them. What happens on the first catch is undefined.

2> Why. in each run, the first output row
is different from the second one?

Because they are different objects.


Thanks for the help.


--
Bob Hairgrove
[email]rhairgroveNoSpam (AT) Pleasebigfoot (DOT) com[/email]

Back to top
Dario
Guest





PostPosted: Fri Sep 26, 2003 11:23 am    Post subject: Re: Troubles with exception::what() Reply with quote

Bob Hairgrove wrote:

Quote:
BTW, one shouldn't ever put "using namespace ...<anything>" in a
header file... for toy programs such as this, it is probably OK.

I use "using namespace ...<anything>" only in my *.cpp files.

Quote:
He also should have a *virtual* destructor.

Yes, in my "actual" code I have it.

Quote:
It might be a better idea to derive the class from std::exception and not from one of its
derived classes because not every implementation of the STL uses a
virtual destructor in the derived classes. In some of them, it will
work; in others, maybe not.

But my LogicError is a logic_error and not a generic exception.
So I will continue to derive from logic_error.

Quote:
Incidently, gcc 3.3.1 needed this:

~LogicError() throw() {};

It seems to make sense since the destructor of the base class also
specified throw().

OK.

Quote:
void f() {
throw LogicError("child description");
}
int main() {
try {
f();
} catch(exception e) {

Exception caught by value - a copy of "exception" is made here.

Well this means that you're not using the method what above.

cout << "e.what=[" << e.what() << "]" << endl;
}
try {
f();
} catch(exception & e) {

Exception caught by reference - cool, now you will get the right what
becuase you are actually using a LogicError object and not an
"exception" object copied.

OK.

Quote:
Two questions to the C++ gurus:
1> Which is the expected ANSI-C++ behaviour?

All of them. What happens on the first catch is undefined.

OK. Understood.

Quote:
2> Why. in each run, the first output row
is different from the second one?

Because they are different objects.

OK. Understood.

Thanks.

- Dario


Back to top
Jerry Coffin
Guest





PostPosted: Fri Sep 26, 2003 3:08 pm    Post subject: Re: Troubles with exception::what() Reply with quote

In article <3f73f5dc.2186694 (AT) news (DOT) webshuttle.ch>,
[email]rhairgroveNotAValid (AT) EMailAddressbigfoot (DOT) com[/email] says...

[ ... ]

Quote:
#include <stdexcept
#include #include using namespace std;

BTW, one shouldn't ever put "using namespace ... header file...

....at namespace scope. Something like this:

#include <iostream>

class X {
using namespace std;

// declarations including "ostream" instead of "std::ostream".
};

is perfectly reasonable. The using declaration follows scope rules, so
after the end of the declaration of 'X', the using declaration no longer
has any effect.

[ ... ]

Quote:
He also should have a *virtual* destructor.

He does. He's deriving indirectly from class exception, which is
required to have a virtual destructor ($18.6.1). Since its destructor
is virtual, the destructors of all derived classes are also virtual
($12.4/7). Since he hasn't declared a dtor explicitly, it's declared
implicitly ($12.4/3). Since he hasn't defined it explicitly either, it
will be defined implicitly ($12.4/5).

Quote:
It might be a better idea
to derive the class from std::exception and not from one of its
derived classes because not every implementation of the STL uses a
virtual destructor in the derived classes. In some of them, it will
work; in others, maybe not.

If the base class destructor is virtual, the destructors of _all_
derived classes are virtual. This is an absolute requirement of the
language, and does not depend on the implementation of the standard
library -- any compiler that makes a derived dtor non-virtual when the
base dtor is virtual is simply _horribly_ broken -- to the point that I
don't think it's worth discussing in the context of C++ at all.

--
Later,
Jerry.

The universe is a figment of its own imagination.

Back to top
Ron Natalie
Guest





PostPosted: Fri Sep 26, 2003 3:15 pm    Post subject: Re: Troubles with exception::what() Reply with quote


"Dario" <dario (AT) despammed (DOT) com> wrote


Quote:
} catch(exception e) {
cout << "e.what=[" << e.what() << "]" << endl;
}
When I run it on Windows (Visual Studio 6.0) I obtain:
e.what=[]
e.what=[child description]

When I run it on Windows (Visual Studio 7.1) I obtain:
e.what=[Unknown exception]
e.what=[child description]


This is to be expected. In the first try/catch you have slice your
thrown exception into an "exception". The dynamic type and
static type of e are the same. So in this case whatever implementation
defined string exception::what() prints is what you get.

In your second try/catch, you catch byreferece, therefore e still has
it's dynamic type of LogicError. The virtual what() function then
runs LogicError::what().



Back to top
Ron Natalie
Guest





PostPosted: Fri Sep 26, 2003 3:17 pm    Post subject: Re: Troubles with exception::what() Reply with quote


"Bob Hairgrove" <rhairgroveNotAValid (AT) EMailAddressbigfoot (DOT) com> wrote


Quote:

He also should have a *virtual* destructor.

The destructor is already virtual. std::exception's destructor is virtual so all
of it's children also have virtual destructors.



Back to top
Gianni Mariani
Guest





PostPosted: Sat Sep 27, 2003 3:47 am    Post subject: Re: Troubles with exception::what() Reply with quote

Dario wrote:
Quote:

....
Thanks for the help.

- Dario


No-one is able to give me an help ?

There were posts from Ron N. and myself. What's the issue ?


Back to top
Ron Natalie
Guest





PostPosted: Sat Sep 27, 2003 2:17 pm    Post subject: Re: Troubles with exception::what() Reply with quote


"Dario" <dario (AT) despammed (DOT) com> wrote


Quote:

No-one is able to give me an help ?

I thought I did. Maybe we misunderstood your question.

The program behaves as expected. When you convert a derived class (LogicError)
a base class (exception), the object you create is the base class (exception). It's
not polymorphic, it is the base class initialzed with pieces of your derived class.

The reason it behaves differently between Linux an WIndows, is that exception::what()
returns diferent things on those machines. If you wrote:

int main() {
exception e;
cout << e.what() << endl;
}

and ran it on both machiens, you'd get the same thing you see for your first print in your
program. The standard just says the string is "implementation defined." In the case of
VC++ 6.0 it appears to just be an empty string. In VC++ 7 it is "unkonwn exception".
On Linux, it's "exception." All of these are technically correct.

When you use a reference to the base class instead, you have a polymorphic reference
to the derived object with the static type of the base class. In this case, the virtual function
what() returns your "child description."

Does this help? If not, you'll have to ask a more detailed question and we'll be glad to
explain further.

-Ron



Back to top
Bob Hairgrove
Guest





PostPosted: Sat Sep 27, 2003 4:37 pm    Post subject: Re: Troubles with exception::what() Reply with quote

On Fri, 26 Sep 2003 11:17:22 -0400, "Ron Natalie" <ron (AT) sensor (DOT) com>
wrote:

Quote:

"Bob Hairgrove" <rhairgroveNotAValid (AT) EMailAddressbigfoot (DOT) com> wrote



He also should have a *virtual* destructor.

The destructor is already virtual. std::exception's destructor is virtual so all
of it's children also have virtual destructors.


He is deriving his class from std::logic_error, not std::exception. We
had problems deriving from std::invalid_argument when we ported an
application from BCB5 using RogueWave STL to BCB6 using STLPort. It
wouldn't compile because STLPort's implementation of
std::invalid_argument does not have a virtual destructor (our class
did). At least, that was the error message we received. I assumed that
std::logic_error might suffer under the same symptom. Now, maybe
STLPort is broken? I don't know what the standard says, but I know
that we had problems because of the different implementations of the
STL, and that is why I gave that pieve of advice.


--
Bob Hairgrove
[email]rhairgroveNoSpam (AT) Pleasebigfoot (DOT) com[/email]

Back to top
Kevin Goodsell
Guest





PostPosted: Sat Sep 27, 2003 5:55 pm    Post subject: Re: Troubles with exception::what() Reply with quote

Bob Hairgrove wrote:

Quote:
He is deriving his class from std::logic_error, not std::exception. We
had problems deriving from std::invalid_argument when we ported an
application from BCB5 using RogueWave STL to BCB6 using STLPort. It
wouldn't compile because STLPort's implementation of
std::invalid_argument does not have a virtual destructor (our class
did). At least, that was the error message we received. I assumed that
std::logic_error might suffer under the same symptom. Now, maybe
STLPort is broken? I don't know what the standard says,
snip


10.3 Virtual functions [class.virtual]

2 If a virtual member function vf is declared in a class Base and in a
class Derived, derived directly or indirectly from Base, a member
function vf with the same name and same parameter list as Base::vf is
declared, then Derived::vf is also virtual (whether or not it is so
declared)

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.


Back to top
Ron Natalie
Guest





PostPosted: Mon Sep 29, 2003 1:56 pm    Post subject: Re: Troubles with exception::what() Reply with quote


"Bob Hairgrove" <rhairgroveNotAValid (AT) EMailAddressbigfoot (DOT) com> wrote


Quote:
The destructor is already virtual. std::exception's destructor is virtual so all
of it's children also have virtual destructors.


He is deriving his class from std::logic_error, not std::exception.

And logic_error is dervied from exeception. As I said, std::exception
and EVERYTHING DERIVED FROM IT has a virtual destructor.

Quote:
We
had problems deriving from std::invalid_argument when we ported an
application from BCB5 using RogueWave STL to BCB6 using STLPort. It
wouldn't compile because STLPort's implementation of
std::invalid_argument does not have a virtual destructor (our class
did).

Something else is wrong. All of these classes are derived from a class
with a virtual destructor. That makes their destructors virtual. If you had
problems, it was because something was seriously wrokng with your impelemntation.



Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.