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 12 11027
Dario wrote: 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(); }
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.
On 26 Sep 2003 04:47:25 GMT, Gianni Mariani <gi*******@mariani.ws>
wrote: Dario wrote: The following simple program behaves differently in Windows and Linux .
#include <stdexcept> #include <iostream> #include <string> using namespace std;
BTW, one shouldn't ever put "using namespace ...<anything>" in a
header file... for toy programs such as this, it is probably OK.
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. 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 rh**************@Pleasebigfoot.com
In article <3f**************@news.webshuttle.ch>, rh*****************@EMailAddressbigfoot.com says...
[ ... ] #include <stdexcept> #include <iostream> #include <string> using namespace std; BTW, one shouldn't ever put "using namespace ...<anything>" in a 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.
[ ... ]
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).
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.
"Dario" <da***@despammed.com> wrote in message news:bk**********@fata.cs.interbusiness.it... } 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().
"Bob Hairgrove" <rh*****************@EMailAddressbigfoot.com> wrote in message news:3f**************@news.webshuttle.ch... 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. 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
No-one is able to give me an help ?
- Dario
Dario wrote:
.... 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 ?
Bob Hairgrove wrote: 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.
He also should have a *virtual* destructor.
Yes, in my "actual" code I have it.
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. 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. 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. 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. <2> Why. in each run, the first output row is different from the second one?
Because they are different objects.
OK. Understood.
Thanks.
- Dario
"Dario" <da***@despammed.com> wrote in message news:bk**********@grillo.cs.interbusiness.it... 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
On Fri, 26 Sep 2003 11:17:22 -0400, "Ron Natalie" <ro*@sensor.com>
wrote: "Bob Hairgrove" <rh*****************@EMailAddressbigfoot.com> wrote in message news:3f**************@news.webshuttle.ch...
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 rh**************@Pleasebigfoot.com
Bob Hairgrove wrote: 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.
"Bob Hairgrove" <rh*****************@EMailAddressbigfoot.com> wrote in message news:3f**************@news.webshuttle.ch... 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.
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. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Páll Ólafsson |
last post by:
Hi
I have a problem with the Microsoft.ApplicationBlocks.ExceptionManagement? I
can't get it to work in RELEASE mode? If I run the project in debug mode
the block works fine but when I run the...
|
by: Steven T. Hatton |
last post by:
If I understand correctly, I have no assurance that I can determine the type
of a simple class instance thrown as an exception unless I explicitly catch
it by name. (non-derived classes having no...
|
by: Dave |
last post by:
try
{
...
}
catch (exception e)
{
cout << e.what() << endl;
}
In the code above, e is caught by value rather than polymorphically (assume
|
by: linq936 |
last post by:
Hi,
I have many assert() call in my code, now I am considering to replace
them with exception. The reason I want to do this change is that with
the program going bigger and bigger, it is hard to...
|
by: Tony Johansson |
last post by:
Hello!
When you allocate object dynamically which mean on the heap I find that a
problem when using exception.
What is the prefer method to handle this kind of problem.
//Tony
|
by: James Foreman |
last post by:
I'm building a revenue management tool and this requires some
understanding of how good my forecast accuracy is.
Therefore I'm trying to collect the mean absolute percentage error
(MAPE) on a...
|
by: Larry Rebich |
last post by:
I'm running a very simple web application and get this error. What do I need
to change?
------------------------------------------
Security Exception
Description: The application attempted to...
|
by: Darko Miletic |
last post by:
Recently I wrote a dll in c++ and to simplify the distribution I decided
to link with multithreaded static library (/MT or /MTd option). In debug
everything works fine but in release I get this:
...
|
by: =?Utf-8?B?QW5kcmUgS2xpbW92?= |
last post by:
Hi!
Situation:
simple code read registry value (OpenSubKey -GetValue, as usual).
Requested value exists in registry and has type DWORD, read into the
variable UInt32, access rights granted.
...
|
by: Rina0 |
last post by:
Cybersecurity engineering is a specialized field that focuses on the design, development, and implementation of systems, processes, and technologies that protect against cyber threats and...
|
by: erikbower65 |
last post by:
Using CodiumAI's pr-agent is simple and powerful. Follow these steps:
1. Install CodiumAI CLI: Ensure Node.js is installed, then run 'npm install -g codiumai' in the terminal.
2. Connect to...
|
by: linyimin |
last post by:
Spring Startup Analyzer generates an interactive Spring application startup report that lets you understand what contributes to the application startup time and helps to optimize it. Support for...
|
by: erikbower65 |
last post by:
Here's a concise step-by-step guide for manually installing IntelliJ IDEA:
1. Download: Visit the official JetBrains website and download the IntelliJ IDEA Community or Ultimate edition based on...
|
by: kcodez |
last post by:
As a H5 game development enthusiast, I recently wrote a very interesting little game - Toy Claw ((http://claw.kjeek.com/))。Here I will summarize and share the development experience here, and hope it...
|
by: Taofi |
last post by:
I try to insert a new record but the error message says the number of query names and destination fields are not the same
This are my field names
ID, Budgeted, Actual, Status and Differences
...
|
by: Rina0 |
last post by:
I am looking for a Python code to find the longest common subsequence of two strings. I found this blog post that describes the length of longest common subsequence problem and provides a solution in...
|
by: lllomh |
last post by:
How does React native implement an English player?
|
by: DJRhino |
last post by:
Was curious if anyone else was having this same issue or not....
I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...
| |