473,388 Members | 1,340 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,388 software developers and data experts.

Exception handling the right way

Hi,

I was just browsing the C++ FAQ and stumbled upon the 'mind sets' that
are wrong for using C++ exception handling. I am looking for the 'right'
mind set. I come from a C background, and still use a lot of C style
programming in my C++ programs. Exception handling is one of the things
I never extensively used; with my C-return-codes-mindset I'd put too
many exception handling code in my programs.

Are there any good examples of projects that use it correctly? (As the
FAQ states you should have a system-wide perspective, simple exception
howto's are not really useful).

Bart
Sep 8 '08 #1
18 1623
"Bart Friederichs" <bf@tbwb.nlwrote in message
news:48*********************@news.xs4all.nl...
Hi,

I was just browsing the C++ FAQ and stumbled upon the 'mind sets' that
are wrong for using C++ exception handling. I am looking for the 'right'
mind set. I come from a C background, and still use a lot of C style
programming in my C++ programs. Exception handling is one of the things
I never extensively used; with my C-return-codes-mindset I'd put too
many exception handling code in my programs.

Are there any good examples of projects that use it correctly? (As the
FAQ states you should have a system-wide perspective, simple exception
howto's are not really useful).
Take a look at this first:

http://www.ddj.com/cpp/184403758

Sep 8 '08 #2
Bart Friederichs wrote:
Hi,

I was just browsing the C++ FAQ and stumbled upon the 'mind sets' that
are wrong for using C++ exception handling. I am looking for the 'right'
mind set. I come from a C background, and still use a lot of C style
programming in my C++ programs. Exception handling is one of the things
I never extensively used; with my C-return-codes-mindset I'd put too
many exception handling code in my programs.
What do you mean under "too many exception handling code" ?

You should handle an exception at the point when you know how to resolve
the error.
Are there any good examples of projects that use it correctly? (As the
FAQ states you should have a system-wide perspective, simple exception
howto's are not really useful).
I like this explanation:
http://www.boost.org/community/error_handling.html
Sep 8 '08 #3
anon wrote:
I like this explanation:
http://www.boost.org/community/error_handling.html
Thanks for the pointers, and I started a little experimenting. Soon I
ran into this problem:

int main () {
A *a; B *b; C *c;
try {
a = new A();
b = new B();
c = new C();
} catch (...) {
delete a;
delete b;
delete c;
}

return 0;
}

Which results in a runtime error when B's contructor throws an
exception. How to correctly free resources on the heap in exception
handling?

Bart
Sep 9 '08 #4
"Bart Friederichs" <bf@tbwb.nlwrote in message
news:48*********************@news.xs4all.nl...
anon wrote:
>I like this explanation:
http://www.boost.org/community/error_handling.html

Thanks for the pointers, and I started a little experimenting. Soon I
ran into this problem:

int main () {
A *a; B *b; C *c;
try {
a = new A();
b = new B();
c = new C();
} catch (...) {
delete a;
delete b;
delete c;
}

return 0;
}
there are some errors here... Simple fix:
int main() {
A* a = NULL;
B* b = NULL;
C* c = NULL;
try {
a = new A;
b = new B;
c = new C;
} catch(...) {
delete a;
delete b;
delete c;
}
return 0;
}

or, even better:
int main() {
std::auto_ptr<Aa(new A);
std::auto_ptr<Bb(new B);
std::auto_ptr<Cc(new C);
return 0;
}

Which results in a runtime error when B's contructor throws an
exception. How to correctly free resources on the heap in exception
handling?

Sep 9 '08 #5

"Chris M. Thomasson" <no@spam.invalidwrote in message
news:jU*******************@newsfe07.iad...
"Bart Friederichs" <bf@tbwb.nlwrote in message
news:48*********************@news.xs4all.nl...
>anon wrote:
>>I like this explanation:
http://www.boost.org/community/error_handling.html

Thanks for the pointers, and I started a little experimenting. Soon I
ran into this problem:

int main () {
A *a; B *b; C *c;
try {
a = new A();
b = new B();
c = new C();
} catch (...) {
delete a;
delete b;
delete c;
}

return 0;
}

there are some errors here... Simple fix:
int main() {
A* a = NULL;
B* b = NULL;
C* c = NULL;
try {
a = new A;
b = new B;
c = new C;
} catch(...) {
delete a;
delete b;
delete c;
}
return 0;
}

Ummm... Well, I forgot to destroy the pointers in the case of no
exception!!! You could do this:

int main() {
A* a = NULL;
B* b = NULL;
C* c = NULL;
try {
a = new A;
b = new B;
c = new C;
} catch(...) {
}
delete a;
delete b;
delete c;
return 0;
}
Man, that looks like total crap when compared to the version which makes use
of smart pointers...
OUCH!

;^(

or, even better:
int main() {
std::auto_ptr<Aa(new A);
std::auto_ptr<Bb(new B);
std::auto_ptr<Cc(new C);
return 0;
}

>Which results in a runtime error when B's contructor throws an
exception. How to correctly free resources on the heap in exception
handling?

Sep 9 '08 #6
Chris M. Thomasson wrote:
int main() {
std::auto_ptr<Aa(new A);
std::auto_ptr<Bb(new B);
std::auto_ptr<Cc(new C);
return 0;
}
This terminates when B() throws, simply adding the try-catch around it
seems to fix that.

Learned again something; the smart pointers.

Bart
Sep 9 '08 #7
On 9 Sep, 10:15, Bart Friederichs <b...@tbwb.nlwrote:
Chris M. Thomasson wrote:
int main() {
*std::auto_ptr<Aa(new A);
*std::auto_ptr<Bb(new B);
*std::auto_ptr<Cc(new C);
*return 0;
}

This terminates when B() throws, simply adding the try-catch around it
seems to fix that.
the whole point is to avoid a try-catch! What do you mean it
terminates? The program will terminate whether new B throws or not.
Learned again something; the smart pointers.
try putting print statements in the CTOR and DTOR
of A, B and C and you should be able to work out
what's going on.

--
Nick Keighley


Sep 9 '08 #8
In article <48*********************@news.xs4all.nl>,
Bart Friederichs <bf@tbwb.nlwrote:
>Chris M. Thomasson wrote:
>int main() {
std::auto_ptr<Aa(new A);
std::auto_ptr<Bb(new B);
std::auto_ptr<Cc(new C);
return 0;
}

This terminates when B() throws, simply adding the try-catch around it
seems to fix that.

Learned again something; the smart pointers.

Bart
Even better: don't use pointers:

int main()
{
A a;
B b;
C c;
return 0;
}

In a lot of case, there is no need to "new" the object. Automatic
variable will do very well.

If you need to klnow that there was an exception:

int main()
{
try
{
A a;
B b;
C c;
return 0;
}
catch(...)
{
std::cout << "Caught an exception\n";
return -1;
}
}

To get the mindset right, learn about RAII. e.g.
http://en.wikipedia.org/wiki/Resourc...initialization

I like Alan Griffiths article "Here be Dragons" as an introduction:
http://www.octopull.demon.co.uk/c++/dragons/

Yannick
Sep 9 '08 #9
On Tue, 09 Sep 2008 10:48:29 +0200, Bart Friederichs <bf@tbwb.nlwrote:
anon wrote:
>I like this explanation:
http://www.boost.org/community/error_handling.html

Thanks for the pointers, and I started a little experimenting. Soon I
ran into this problem:

int main () {
A *a; B *b; C *c;
try {
a = new A();
b = new B();
c = new C();
} catch (...) {
delete a;
delete b;
delete c;
}

return 0;
}

Which results in a runtime error when B's contructor throws an
exception. How to correctly free resources on the heap in exception
handling?
Usually you can side-step this.

int main()
{
A a;
B b;
C c;
exit 0;
}

Or if there is some extraordinary reason you have to new them, maybe
their lifetime fits into an object? I find this is often the case.

class MeaningfulSomething {
public:
MeaningfulSomething(args)
: a_(new A()),
b_(new B()),
c_(new C())
{}
~MeaningfulSomething() { delete ... }
A * const a_;
B * const b_;
C * const c_;
};

/Jorgen

--
// Jorgen Grahn <grahn@ Ph'nglui mglw'nafh Cthulhu
\X/ snipabacken.se R'lyeh wgah'nagl fhtagn!
Sep 9 '08 #10
On Sep 9, 12:25 pm, Nick Keighley <nick_keighley_nos...@hotmail.com>
wrote:
On 9 Sep, 10:15, Bart Friederichs <b...@tbwb.nlwrote:
Chris M. Thomasson wrote:
int main() {
std::auto_ptr<Aa(new A);
std::auto_ptr<Bb(new B);
std::auto_ptr<Cc(new C);
return 0;
}
This terminates when B() throws, simply adding the try-catch
around it seems to fix that.
the whole point is to avoid a try-catch!
There's no point in using exceptions if you don't have a
try/catch somewhere. Typically, the main function is the place,
at least in single threaded applications.
What do you mean it terminates? The program will terminate
whether new B throws or not.
But it will not terminate in the same manner.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Sep 9 '08 #11
On Sep 9, 2:57 pm, Jorgen Grahn <grahn+n...@snipabacken.sewrote:
class MeaningfulSomething {
public:
MeaningfulSomething(args)
: a_(new A()),
b_(new B()),
c_(new C())
{}
~MeaningfulSomething() { delete ... }
A * const a_;
B * const b_;
C * const c_;
};
This will leak memory if any of the new expressions throws.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Sep 9 '08 #12
Bart Friederichs wrote:
Yannick Tremblay wrote:
>Don't get me wrong, I really respect the writings of Alexandrescu as
well he has brought to the C++ community. However, I have serious
doubts about recommending his writing to a beginner that is trying to
figure out exceptions. I fear that he would get lost in the
complexity of the details and templates presented in this article (or
in Loki and Mordern C++).

I am not a beginner. I understand the scopeguard completely. I myself
though have serious doubts about the usability of it in our applications
(time critical automation control). I get a slight sense of extra
clutter in my code.

I just never seriously used exception handling, because I never needed
it. I want to figure out now, if I *really* don't need it, or if I am
missing on some useful programming concepts.
If you are programming in c++, then you are missing very useful
programming concepts.
Sep 10 '08 #13
Nick Keighley wrote:
On 9 Sep, 10:15, Bart Friederichs <b...@tbwb.nlwrote:
>Chris M. Thomasson wrote:
>>int main() {
std::auto_ptr<Aa(new A);
std::auto_ptr<Bb(new B);
std::auto_ptr<Cc(new C);
return 0;
}
This terminates when B() throws, simply adding the try-catch around it
seems to fix that.

the whole point is to avoid a try-catch! What do you mean it
terminates? The program will terminate whether new B throws or not.
without try-catch:

bf@bf-laptop:~/playground$ ./test
A constructed.
B constructed.
terminate called after throwing an instance of 'int'
Aborted

with try-catch:
bf@bf-laptop:~/playground$ ./test
A constructed.
B constructed.
A destroyed.

>Learned again something; the smart pointers.

try putting print statements in the CTOR and DTOR
of A, B and C and you should be able to work out
what's going on.
That is what I did.

Bart
Sep 10 '08 #14
Yannick Tremblay wrote:
Even better: don't use pointers:

int main()
{
A a;
B b;
C c;
return 0;
}
That is not the point. Sometimes it is needed to use pointers. I also
want to know how to handle excpetions in that case correctly.
To get the mindset right, learn about RAII. e.g.
http://en.wikipedia.org/wiki/Resourc...initialization
Slowly I am starting to understand the mindset. And I have the feeling
it is not really useful for our applications, since there are only few
data-objects, but mostly process-objects. All data is managed in an SQL
database (to 'survive' restarts or crashes).
>
I like Alan Griffiths article "Here be Dragons" as an introduction:
http://www.octopull.demon.co.uk/c++/dragons/
Thanks, I'll read that.

Bart
Sep 10 '08 #15
In article <48*********************@news.xs4all.nl>,
Bart Friederichs <bf@tbwb.nlwrote:
>Yannick Tremblay wrote:
>Even better: don't use pointers:

int main()
{
A a;
B b;
C c;
return 0;
}

That is not the point. Sometimes it is needed to use pointers. I also
want to know how to handle excpetions in that case correctly.
I did write:
In a lot of case, there is no need to "new" the object. Automatic
variable will do very well.

The point is that in your example, there is no need to use "new". By
defaults, in C++, you should use a local automatic variables.
Globals, statics and dynamically allocated ones are to be used when
there is a specific need for them.

In general, I would recommend never to dynamically allocate to a raw
pointer. I.e. if you must do dynamic allocation, always have the
result owned by: std::auto_ptr<>, shared_ptr<>, a member of a RAII
class that will automatically clean up in it's destructor. Only use
raw pointers as a reference to and object that is owned by something
else. Obviously, there are exceptions to this.

>To get the mindset right, learn about RAII. e.g.
http://en.wikipedia.org/wiki/Resourc...initialization

Slowly I am starting to understand the mindset. And I have the feeling
it is not really useful for our applications, since there are only few
data-objects, but mostly process-objects. All data is managed in an SQL
database (to 'survive' restarts or crashes).
Actually, it is possible to use databases with real C++ and RAII.
Have a look at pqxx: http://pqxx.org/development/libpqxx/. This is a
very nice real C++ interface to Postgresql. In fact, using pqxx with
transaction objects and exception makes data management amuch much
simpler than using a C-style interface.

Yannick

Sep 10 '08 #16

"Yannick Tremblay" <yt******@nyx.nyx.netwrote in message
news:12**************@irys.nyx.net...
In article <ZU***************@newsfe01.iad>,
Chris M. Thomasson <no@spam.invalidwrote:
>>"Bart Friederichs" <bf@tbwb.nlwrote in message
news:48*********************@news.xs4all.nl...
>>Hi,

I was just browsing the C++ FAQ and stumbled upon the 'mind sets' that
are wrong for using C++ exception handling. I am looking for the 'right'
mind set. I come from a C background, and still use a lot of C style
programming in my C++ programs. Exception handling is one of the things
I never extensively used; with my C-return-codes-mindset I'd put too
many exception handling code in my programs.

Are there any good examples of projects that use it correctly? (As the
FAQ states you should have a system-wide perspective, simple exception
howto's are not really useful).

Take a look at this first:

http://www.ddj.com/cpp/184403758

Hmm, Alexandrescu & Marginean advanced ScopeGuard article...

Don't get me wrong, I really respect the writings of Alexandrescu as
well he has brought to the C++ community. However, I have serious
doubts about recommending his writing to a beginner that is trying to
figure out exceptions. I fear that he would get lost in the
complexity of the details and templates presented in this article (or
in Loki and Mordern C++).
[...]

Of course the beginner would not necessarily "need" to implement the
details. Luckily, they can simply download the source-code from the article
and include the headers in their projects. IMHO, it would be very nice if
the STL had something analogous to ScopeGuard...

Sep 11 '08 #17
"Bart Friederichs" <bf@tbwb.nlwrote in message
news:48*********************@news.xs4all.nl...
Chris M. Thomasson wrote:
>int main() {
std::auto_ptr<Aa(new A);
std::auto_ptr<Bb(new B);
std::auto_ptr<Cc(new C);
return 0;
}

This terminates when B() throws, simply adding the try-catch around it
seems to fix that.

Learned again something; the smart pointers.
You could do:
__________________________________________________ ______________
int main() {
{
std::auto_ptr<Aa;
std::auto_ptr<Bb;
std::auto_ptr<Cc;

try {
a.reset(new A);
b.reset(new B);
c.reset(new C);
} catch (...) {
[whatever];
}
}

// everything has been "cleaned up"...

return 0;
}

__________________________________________________ ______________

Sep 11 '08 #18
On Tue, 9 Sep 2008 06:07:27 -0700 (PDT), James Kanze <ja*********@gmail.comwrote:
On Sep 9, 2:57 pm, Jorgen Grahn <grahn+n...@snipabacken.sewrote:
>class MeaningfulSomething {
public:
MeaningfulSomething(args)
: a_(new A()),
b_(new B()),
c_(new C())
{}
~MeaningfulSomething() { delete ... }
A * const a_;
B * const b_;
C * const c_;
};

This will leak memory if any of the new expressions throws.
Oops, sorry. I should think before posting advice. It will leak
*resources* in general -- which may be even worse than a memory leak.

/Jorgen

--
// Jorgen Grahn <grahn@ Ph'nglui mglw'nafh Cthulhu
\X/ snipabacken.se R'lyeh wgah'nagl fhtagn!
Sep 16 '08 #19

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Babu | last post by:
Hi, I am a Perl newbie and have a doubt on Perl exception handling. My understanding regarding exception handling is execute a piece of code, if any exception occurs, handle the exception and...
7
by: Noor | last post by:
please tell the technique of centralize exception handling without try catch blocks in c#.
6
by: vkreddy_in | last post by:
HI Currently i am handling excpetion using TRY/catch in my code.I am looking for solution some thing like this. if an excrption is occured then 1.call a CALLBACK function in a DLL 2.print the...
44
by: craig | last post by:
I am wondering if there are some best practices for determining a strategy for using try/catch blocks within an application. My current thoughts are: 1. The code the initiates any high-level...
6
by: Robin Riley | last post by:
Hi, I have a .NET solution that contains a dll project and a tester application project which, of course, invokes the dll. The dll project has exception handling in it. What's happening is that...
5
by: Bry | last post by:
I've created a class that offers an enhanced way of handling fatal exceptions. The class allows the user to optionaly submit a http based anonymous error report to myself, and also records details...
41
by: Zytan | last post by:
Ok something simple like int.Parse(string) can throw these exceptions: ArgumentNullException, FormatException, OverflowException I don't want my program to just crash on an exception, so I must...
2
by: Carol | last post by:
Exception may be thrown in the code inside the try block. I want to handling the SqlException with State == 1 in a special way, and for all others I want to use a general way to handle. Which of...
1
by: George2 | last post by:
Hello everyone, Such code segment is used to check whether function call or exception- handling mechanism runs out of memory first (written by Bjarne), void perverted() { try{
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.