Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What type should I catch if I throw a string literal?

Tags:

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?

like image 855
Grzenio Avatar asked Jan 28 '11 18:01

Grzenio


People also ask

What is the type of a string literal?

A string literal type is a type whose expected value is a string with textual contents equal to that of the string literal type. In other words: A variable of a string literal type can only be assigned the exact string value specified in the string literal type.

How do you recognize a string literal?

A "string literal" is a sequence of characters from the source character set enclosed in double quotation marks (" "). String literals are used to represent a sequence of characters which, taken together, form a null-terminated string. You must always prefix wide-string literals with the letter L.

What is an example of a string literal?

A string literal is a sequence of zero or more characters enclosed within single quotation marks. The following are examples of string literals: 'Hello, world!' 'He said, "Take it or leave it."'

What are the two types of string literals?

A string literal with the prefix L is a wide string literal. A string literal without the prefix L is an ordinary or narrow string literal.


2 Answers

You need to catch it with char const* instead of char*. Neither anything like std::string nor char* 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 handler is a match for an exception object of type E if

  • The handler is of type cv T or cv T& and E and T are the same type (ignoring the top-level cv-qualifiers), or
  • the handler is of type cv T or cv T& and T is an unambiguous public base class of E, or
  • the handler is of type cv1 T* cv2 and E is a pointer type that can be converted to the type of the handler by either or both of

    • a standard pointer conversion (4.10) not involving conversions to pointers to private or protected or ambiguous classes
    • a qualification conversion

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 a char*, because at the time it matches, it needs to match the char* to a char const*, which would throw away a const (a qualification conversion is only allowed to add const). The special conversion of a string literal to char* is only considered when you need to convert a string literal specifically.

like image 116
Johannes Schaub - litb Avatar answered Oct 07 '22 20:10

Johannes Schaub - litb


Try adding const to the types you're catching, const char* (possibly const char* const).

like image 21
luke Avatar answered Oct 07 '22 22:10

luke