I am writing a pretty simple application in C++ using g++ under Linux and I am trying to throw some raw strings as exceptions (yes, I know, its not a good practise).
I have the following code (simplified):
int main()
{
try
{
throw "not implemented";
}
catch(std::string &error)
{
cerr<<"Error: "<<error<<endl;
}
catch(char* error)
{
cerr<<"Error: "<<error<<endl;
}
catch(...)
{
cerr<<"Unknown error"<<endl;
}
}
And I get Unknow error
on the console. But if I static cast the literal string to either std::string
or char *
it prints Error: not implemented
as expected. My question is: so what is the type I should catch if I don't want to use static casts?
Try adding
const
to the types you're catching,const char*
(possiblyconst char* const
).You need to catch it with
char const*
instead ofchar*
. Neither anything likestd::string
norchar*
will catch it.Catching has restricted rules with regard to what types it match. The spec says (where "cv" means "const/volatile combination" or neither of them).
A string literal has type
char const[N]
, but throwing an array will decay the array and actually throws a pointer to its first element. So you cannot catch a thrown string literal by achar*
, because at the time it matches, it needs to match thechar*
to achar const*
, which would throw away a const (a qualification conversion is only allowed to add const). The special conversion of a string literal tochar*
is only considered when you need to convert a string literal specifically.Check out the section 2.14.5 of the standard specification, it treats types and kinds of string literals on 3 pages. Don't do what you started to do, just say:
along with proper
Is there something wrong with this "normal" approach...?
The problem is that you're trying to catch something that is a const. The following will work:
catch(const char* error) { cerrThe exact type of a string literal is an array of const characters (
const char [15]
for your example, since the NUL terminator is included). The array decays toconst char*
when thrown, which is independent of the length.The type of a string literal is
char const *
. There's a (deprecated) conversion tochar *
provided for backward compatibility with existing code (but you still have to treat it asconst
-- any attempt at modification gives UB).As such, code like this should work: