Is the `std::exception`, in its current form, redundant?
up vote
9
down vote
favorite
Usually, when I want to create my own exception, I inherit from std::exception
or std::runtime_error
.
Is there anything that stops me from creating my own empty "tag-class"?
class out_of_bounds_access {}; // or:
class memory_leak {};
and throw just that?
After all, mostly, it's the class-name that carries information about what went wrong not the members of the exception class.
Ok, so I assumed this is a bad idea, but why? Why is this a bad idea?
P.S. I know there are cases in which "custom-made" exceptions carry information that latter is used to determine the correct approach to solve the problem...
However, if you think about it, cases like that can, very often (not always, but often), be re-done to throw & catch multiple different tag-classes instead of just a single one (with "content").
c++ exception
|
show 2 more comments
up vote
9
down vote
favorite
Usually, when I want to create my own exception, I inherit from std::exception
or std::runtime_error
.
Is there anything that stops me from creating my own empty "tag-class"?
class out_of_bounds_access {}; // or:
class memory_leak {};
and throw just that?
After all, mostly, it's the class-name that carries information about what went wrong not the members of the exception class.
Ok, so I assumed this is a bad idea, but why? Why is this a bad idea?
P.S. I know there are cases in which "custom-made" exceptions carry information that latter is used to determine the correct approach to solve the problem...
However, if you think about it, cases like that can, very often (not always, but often), be re-done to throw & catch multiple different tag-classes instead of just a single one (with "content").
c++ exception
3
For fun, your coworkers will love you for it, you can also just throw string literals or integers. It's not required to throw objects at all.
– john
Dec 3 at 12:30
2
The main difference is thatstd::exception
haswhat
, so in case of catchingstd::exception &
, you can print/log some info about it. If youcatch (...)
, you cannot print/log it in a standard conformant way. If you don't care about this, feel free to use your own exception classes.
– geza
Dec 3 at 12:35
5
@john Well, those are objects too :)
– Lightness Races in Orbit
Dec 3 at 12:36
@LightnessRacesinOrbit maybe in Java. Int is not a class or object in c++.
– lalala
Dec 3 at 18:43
3
@lalala The opposite, actually. The C++ standard uses the term "object" to refer to values of any type at all, including non-class types: anything that has a storage location. Java does no such thing, and uses "object" to mean "an instance of a class", which does not include ints.
– amalloy
Dec 3 at 19:38
|
show 2 more comments
up vote
9
down vote
favorite
up vote
9
down vote
favorite
Usually, when I want to create my own exception, I inherit from std::exception
or std::runtime_error
.
Is there anything that stops me from creating my own empty "tag-class"?
class out_of_bounds_access {}; // or:
class memory_leak {};
and throw just that?
After all, mostly, it's the class-name that carries information about what went wrong not the members of the exception class.
Ok, so I assumed this is a bad idea, but why? Why is this a bad idea?
P.S. I know there are cases in which "custom-made" exceptions carry information that latter is used to determine the correct approach to solve the problem...
However, if you think about it, cases like that can, very often (not always, but often), be re-done to throw & catch multiple different tag-classes instead of just a single one (with "content").
c++ exception
Usually, when I want to create my own exception, I inherit from std::exception
or std::runtime_error
.
Is there anything that stops me from creating my own empty "tag-class"?
class out_of_bounds_access {}; // or:
class memory_leak {};
and throw just that?
After all, mostly, it's the class-name that carries information about what went wrong not the members of the exception class.
Ok, so I assumed this is a bad idea, but why? Why is this a bad idea?
P.S. I know there are cases in which "custom-made" exceptions carry information that latter is used to determine the correct approach to solve the problem...
However, if you think about it, cases like that can, very often (not always, but often), be re-done to throw & catch multiple different tag-classes instead of just a single one (with "content").
c++ exception
c++ exception
edited Dec 3 at 12:23
asked Dec 3 at 12:16
cukier9a7b5
461414
461414
3
For fun, your coworkers will love you for it, you can also just throw string literals or integers. It's not required to throw objects at all.
– john
Dec 3 at 12:30
2
The main difference is thatstd::exception
haswhat
, so in case of catchingstd::exception &
, you can print/log some info about it. If youcatch (...)
, you cannot print/log it in a standard conformant way. If you don't care about this, feel free to use your own exception classes.
– geza
Dec 3 at 12:35
5
@john Well, those are objects too :)
– Lightness Races in Orbit
Dec 3 at 12:36
@LightnessRacesinOrbit maybe in Java. Int is not a class or object in c++.
– lalala
Dec 3 at 18:43
3
@lalala The opposite, actually. The C++ standard uses the term "object" to refer to values of any type at all, including non-class types: anything that has a storage location. Java does no such thing, and uses "object" to mean "an instance of a class", which does not include ints.
– amalloy
Dec 3 at 19:38
|
show 2 more comments
3
For fun, your coworkers will love you for it, you can also just throw string literals or integers. It's not required to throw objects at all.
– john
Dec 3 at 12:30
2
The main difference is thatstd::exception
haswhat
, so in case of catchingstd::exception &
, you can print/log some info about it. If youcatch (...)
, you cannot print/log it in a standard conformant way. If you don't care about this, feel free to use your own exception classes.
– geza
Dec 3 at 12:35
5
@john Well, those are objects too :)
– Lightness Races in Orbit
Dec 3 at 12:36
@LightnessRacesinOrbit maybe in Java. Int is not a class or object in c++.
– lalala
Dec 3 at 18:43
3
@lalala The opposite, actually. The C++ standard uses the term "object" to refer to values of any type at all, including non-class types: anything that has a storage location. Java does no such thing, and uses "object" to mean "an instance of a class", which does not include ints.
– amalloy
Dec 3 at 19:38
3
3
For fun, your coworkers will love you for it, you can also just throw string literals or integers. It's not required to throw objects at all.
– john
Dec 3 at 12:30
For fun, your coworkers will love you for it, you can also just throw string literals or integers. It's not required to throw objects at all.
– john
Dec 3 at 12:30
2
2
The main difference is that
std::exception
has what
, so in case of catching std::exception &
, you can print/log some info about it. If you catch (...)
, you cannot print/log it in a standard conformant way. If you don't care about this, feel free to use your own exception classes.– geza
Dec 3 at 12:35
The main difference is that
std::exception
has what
, so in case of catching std::exception &
, you can print/log some info about it. If you catch (...)
, you cannot print/log it in a standard conformant way. If you don't care about this, feel free to use your own exception classes.– geza
Dec 3 at 12:35
5
5
@john Well, those are objects too :)
– Lightness Races in Orbit
Dec 3 at 12:36
@john Well, those are objects too :)
– Lightness Races in Orbit
Dec 3 at 12:36
@LightnessRacesinOrbit maybe in Java. Int is not a class or object in c++.
– lalala
Dec 3 at 18:43
@LightnessRacesinOrbit maybe in Java. Int is not a class or object in c++.
– lalala
Dec 3 at 18:43
3
3
@lalala The opposite, actually. The C++ standard uses the term "object" to refer to values of any type at all, including non-class types: anything that has a storage location. Java does no such thing, and uses "object" to mean "an instance of a class", which does not include ints.
– amalloy
Dec 3 at 19:38
@lalala The opposite, actually. The C++ standard uses the term "object" to refer to values of any type at all, including non-class types: anything that has a storage location. Java does no such thing, and uses "object" to mean "an instance of a class", which does not include ints.
– amalloy
Dec 3 at 19:38
|
show 2 more comments
1 Answer
1
active
oldest
votes
up vote
26
down vote
accepted
No, nothing stops you from doing this.
However, some code that wants to catch "any exception" will catch const std::exception&
, and if your exception type doesn't derive from std::exception
then that won't work.
Sure, we can catch ...
instead but that's, in my experience, used as a last-ditch "blunt instrument" for avoiding termination due to uncaught exceptions, and can't tell you anything about the exception itself.
Boost exceptions don't derive from std::exception
and it's really annoying.
Why not just make all the exceptions part of this standard hierarchy?
If you don't intend to ever let your exception types make get all the way to the top, then there may not be a practical problem here. But, why take the chance? You lose nothing by adding : std::runtime_error
or somesuch, and the text string that you'll pass to the base is useful information for the diagnosing programmer.
5
tl;dr: the benefit of using std::exception is that I will then be able to approve your pull request ;)
– Lightness Races in Orbit
Dec 3 at 12:41
1
Yes... I completely forget it is easier to justcatch(const std::exception& e)
instead of something likecatch(const out_of_bounds_access& e)
. + the case ofe.what()
Thank you very much!
– cukier9a7b5
Dec 3 at 12:45
5
"Boost exceptions don't derive fromstd::exception
and it's really annoying." – You're meant to useboost::throw_exception
which enables a "normal" catch: "The emitted exception can be intercepted asE &
,std::exception &
, orboost::exception &
."; I'm not defending the design decision, but they do have some magic that "fixes" things.
– Arne Vogel
Dec 3 at 16:07
4
@ArneVogel Ah, bollocks. Do you think it's too late to raise a bug at my old company? :D
– Lightness Races in Orbit
Dec 3 at 16:09
3
@LightnessRacesinOrbit Depends on how old. It was post-dotcom bust, right? ;-) … @cukier9a7b5: BTW, in addition toex.what()
you can usetypeid(ex).name()
, which will give you the mangled type name of the most derived object (becausestd::exception
has virtual methods). This can at least be useful for debug logging. In theory, you could even have associative container of handlers (keyed onstd::type_index
) – but don't overdesign it.
– Arne Vogel
Dec 3 at 16:21
|
show 1 more comment
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
26
down vote
accepted
No, nothing stops you from doing this.
However, some code that wants to catch "any exception" will catch const std::exception&
, and if your exception type doesn't derive from std::exception
then that won't work.
Sure, we can catch ...
instead but that's, in my experience, used as a last-ditch "blunt instrument" for avoiding termination due to uncaught exceptions, and can't tell you anything about the exception itself.
Boost exceptions don't derive from std::exception
and it's really annoying.
Why not just make all the exceptions part of this standard hierarchy?
If you don't intend to ever let your exception types make get all the way to the top, then there may not be a practical problem here. But, why take the chance? You lose nothing by adding : std::runtime_error
or somesuch, and the text string that you'll pass to the base is useful information for the diagnosing programmer.
5
tl;dr: the benefit of using std::exception is that I will then be able to approve your pull request ;)
– Lightness Races in Orbit
Dec 3 at 12:41
1
Yes... I completely forget it is easier to justcatch(const std::exception& e)
instead of something likecatch(const out_of_bounds_access& e)
. + the case ofe.what()
Thank you very much!
– cukier9a7b5
Dec 3 at 12:45
5
"Boost exceptions don't derive fromstd::exception
and it's really annoying." – You're meant to useboost::throw_exception
which enables a "normal" catch: "The emitted exception can be intercepted asE &
,std::exception &
, orboost::exception &
."; I'm not defending the design decision, but they do have some magic that "fixes" things.
– Arne Vogel
Dec 3 at 16:07
4
@ArneVogel Ah, bollocks. Do you think it's too late to raise a bug at my old company? :D
– Lightness Races in Orbit
Dec 3 at 16:09
3
@LightnessRacesinOrbit Depends on how old. It was post-dotcom bust, right? ;-) … @cukier9a7b5: BTW, in addition toex.what()
you can usetypeid(ex).name()
, which will give you the mangled type name of the most derived object (becausestd::exception
has virtual methods). This can at least be useful for debug logging. In theory, you could even have associative container of handlers (keyed onstd::type_index
) – but don't overdesign it.
– Arne Vogel
Dec 3 at 16:21
|
show 1 more comment
up vote
26
down vote
accepted
No, nothing stops you from doing this.
However, some code that wants to catch "any exception" will catch const std::exception&
, and if your exception type doesn't derive from std::exception
then that won't work.
Sure, we can catch ...
instead but that's, in my experience, used as a last-ditch "blunt instrument" for avoiding termination due to uncaught exceptions, and can't tell you anything about the exception itself.
Boost exceptions don't derive from std::exception
and it's really annoying.
Why not just make all the exceptions part of this standard hierarchy?
If you don't intend to ever let your exception types make get all the way to the top, then there may not be a practical problem here. But, why take the chance? You lose nothing by adding : std::runtime_error
or somesuch, and the text string that you'll pass to the base is useful information for the diagnosing programmer.
5
tl;dr: the benefit of using std::exception is that I will then be able to approve your pull request ;)
– Lightness Races in Orbit
Dec 3 at 12:41
1
Yes... I completely forget it is easier to justcatch(const std::exception& e)
instead of something likecatch(const out_of_bounds_access& e)
. + the case ofe.what()
Thank you very much!
– cukier9a7b5
Dec 3 at 12:45
5
"Boost exceptions don't derive fromstd::exception
and it's really annoying." – You're meant to useboost::throw_exception
which enables a "normal" catch: "The emitted exception can be intercepted asE &
,std::exception &
, orboost::exception &
."; I'm not defending the design decision, but they do have some magic that "fixes" things.
– Arne Vogel
Dec 3 at 16:07
4
@ArneVogel Ah, bollocks. Do you think it's too late to raise a bug at my old company? :D
– Lightness Races in Orbit
Dec 3 at 16:09
3
@LightnessRacesinOrbit Depends on how old. It was post-dotcom bust, right? ;-) … @cukier9a7b5: BTW, in addition toex.what()
you can usetypeid(ex).name()
, which will give you the mangled type name of the most derived object (becausestd::exception
has virtual methods). This can at least be useful for debug logging. In theory, you could even have associative container of handlers (keyed onstd::type_index
) – but don't overdesign it.
– Arne Vogel
Dec 3 at 16:21
|
show 1 more comment
up vote
26
down vote
accepted
up vote
26
down vote
accepted
No, nothing stops you from doing this.
However, some code that wants to catch "any exception" will catch const std::exception&
, and if your exception type doesn't derive from std::exception
then that won't work.
Sure, we can catch ...
instead but that's, in my experience, used as a last-ditch "blunt instrument" for avoiding termination due to uncaught exceptions, and can't tell you anything about the exception itself.
Boost exceptions don't derive from std::exception
and it's really annoying.
Why not just make all the exceptions part of this standard hierarchy?
If you don't intend to ever let your exception types make get all the way to the top, then there may not be a practical problem here. But, why take the chance? You lose nothing by adding : std::runtime_error
or somesuch, and the text string that you'll pass to the base is useful information for the diagnosing programmer.
No, nothing stops you from doing this.
However, some code that wants to catch "any exception" will catch const std::exception&
, and if your exception type doesn't derive from std::exception
then that won't work.
Sure, we can catch ...
instead but that's, in my experience, used as a last-ditch "blunt instrument" for avoiding termination due to uncaught exceptions, and can't tell you anything about the exception itself.
Boost exceptions don't derive from std::exception
and it's really annoying.
Why not just make all the exceptions part of this standard hierarchy?
If you don't intend to ever let your exception types make get all the way to the top, then there may not be a practical problem here. But, why take the chance? You lose nothing by adding : std::runtime_error
or somesuch, and the text string that you'll pass to the base is useful information for the diagnosing programmer.
edited Dec 3 at 16:09
answered Dec 3 at 12:20
Lightness Races in Orbit
281k51453769
281k51453769
5
tl;dr: the benefit of using std::exception is that I will then be able to approve your pull request ;)
– Lightness Races in Orbit
Dec 3 at 12:41
1
Yes... I completely forget it is easier to justcatch(const std::exception& e)
instead of something likecatch(const out_of_bounds_access& e)
. + the case ofe.what()
Thank you very much!
– cukier9a7b5
Dec 3 at 12:45
5
"Boost exceptions don't derive fromstd::exception
and it's really annoying." – You're meant to useboost::throw_exception
which enables a "normal" catch: "The emitted exception can be intercepted asE &
,std::exception &
, orboost::exception &
."; I'm not defending the design decision, but they do have some magic that "fixes" things.
– Arne Vogel
Dec 3 at 16:07
4
@ArneVogel Ah, bollocks. Do you think it's too late to raise a bug at my old company? :D
– Lightness Races in Orbit
Dec 3 at 16:09
3
@LightnessRacesinOrbit Depends on how old. It was post-dotcom bust, right? ;-) … @cukier9a7b5: BTW, in addition toex.what()
you can usetypeid(ex).name()
, which will give you the mangled type name of the most derived object (becausestd::exception
has virtual methods). This can at least be useful for debug logging. In theory, you could even have associative container of handlers (keyed onstd::type_index
) – but don't overdesign it.
– Arne Vogel
Dec 3 at 16:21
|
show 1 more comment
5
tl;dr: the benefit of using std::exception is that I will then be able to approve your pull request ;)
– Lightness Races in Orbit
Dec 3 at 12:41
1
Yes... I completely forget it is easier to justcatch(const std::exception& e)
instead of something likecatch(const out_of_bounds_access& e)
. + the case ofe.what()
Thank you very much!
– cukier9a7b5
Dec 3 at 12:45
5
"Boost exceptions don't derive fromstd::exception
and it's really annoying." – You're meant to useboost::throw_exception
which enables a "normal" catch: "The emitted exception can be intercepted asE &
,std::exception &
, orboost::exception &
."; I'm not defending the design decision, but they do have some magic that "fixes" things.
– Arne Vogel
Dec 3 at 16:07
4
@ArneVogel Ah, bollocks. Do you think it's too late to raise a bug at my old company? :D
– Lightness Races in Orbit
Dec 3 at 16:09
3
@LightnessRacesinOrbit Depends on how old. It was post-dotcom bust, right? ;-) … @cukier9a7b5: BTW, in addition toex.what()
you can usetypeid(ex).name()
, which will give you the mangled type name of the most derived object (becausestd::exception
has virtual methods). This can at least be useful for debug logging. In theory, you could even have associative container of handlers (keyed onstd::type_index
) – but don't overdesign it.
– Arne Vogel
Dec 3 at 16:21
5
5
tl;dr: the benefit of using std::exception is that I will then be able to approve your pull request ;)
– Lightness Races in Orbit
Dec 3 at 12:41
tl;dr: the benefit of using std::exception is that I will then be able to approve your pull request ;)
– Lightness Races in Orbit
Dec 3 at 12:41
1
1
Yes... I completely forget it is easier to just
catch(const std::exception& e)
instead of something like catch(const out_of_bounds_access& e)
. + the case of e.what()
Thank you very much!– cukier9a7b5
Dec 3 at 12:45
Yes... I completely forget it is easier to just
catch(const std::exception& e)
instead of something like catch(const out_of_bounds_access& e)
. + the case of e.what()
Thank you very much!– cukier9a7b5
Dec 3 at 12:45
5
5
"Boost exceptions don't derive from
std::exception
and it's really annoying." – You're meant to use boost::throw_exception
which enables a "normal" catch: "The emitted exception can be intercepted as E &
, std::exception &
, or boost::exception &
."; I'm not defending the design decision, but they do have some magic that "fixes" things.– Arne Vogel
Dec 3 at 16:07
"Boost exceptions don't derive from
std::exception
and it's really annoying." – You're meant to use boost::throw_exception
which enables a "normal" catch: "The emitted exception can be intercepted as E &
, std::exception &
, or boost::exception &
."; I'm not defending the design decision, but they do have some magic that "fixes" things.– Arne Vogel
Dec 3 at 16:07
4
4
@ArneVogel Ah, bollocks. Do you think it's too late to raise a bug at my old company? :D
– Lightness Races in Orbit
Dec 3 at 16:09
@ArneVogel Ah, bollocks. Do you think it's too late to raise a bug at my old company? :D
– Lightness Races in Orbit
Dec 3 at 16:09
3
3
@LightnessRacesinOrbit Depends on how old. It was post-dotcom bust, right? ;-) … @cukier9a7b5: BTW, in addition to
ex.what()
you can use typeid(ex).name()
, which will give you the mangled type name of the most derived object (because std::exception
has virtual methods). This can at least be useful for debug logging. In theory, you could even have associative container of handlers (keyed on std::type_index
) – but don't overdesign it.– Arne Vogel
Dec 3 at 16:21
@LightnessRacesinOrbit Depends on how old. It was post-dotcom bust, right? ;-) … @cukier9a7b5: BTW, in addition to
ex.what()
you can use typeid(ex).name()
, which will give you the mangled type name of the most derived object (because std::exception
has virtual methods). This can at least be useful for debug logging. In theory, you could even have associative container of handlers (keyed on std::type_index
) – but don't overdesign it.– Arne Vogel
Dec 3 at 16:21
|
show 1 more comment
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53593701%2fis-the-stdexception-in-its-current-form-redundant%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
3
For fun, your coworkers will love you for it, you can also just throw string literals or integers. It's not required to throw objects at all.
– john
Dec 3 at 12:30
2
The main difference is that
std::exception
haswhat
, so in case of catchingstd::exception &
, you can print/log some info about it. If youcatch (...)
, you cannot print/log it in a standard conformant way. If you don't care about this, feel free to use your own exception classes.– geza
Dec 3 at 12:35
5
@john Well, those are objects too :)
– Lightness Races in Orbit
Dec 3 at 12:36
@LightnessRacesinOrbit maybe in Java. Int is not a class or object in c++.
– lalala
Dec 3 at 18:43
3
@lalala The opposite, actually. The C++ standard uses the term "object" to refer to values of any type at all, including non-class types: anything that has a storage location. Java does no such thing, and uses "object" to mean "an instance of a class", which does not include ints.
– amalloy
Dec 3 at 19:38