Thread: Do the standard exceptions throw?

  1. #1
    Registered User
    Join Date
    Mar 2009
    Posts
    399

    Do the standard exceptions throw?

    I've seen conflicting declarations of the standard exception classes like logic_error etc. In some references their constructors are declared with throw(), and in others they aren't.

    Take out_of_range for example: out_of_range - C++ Reference

    Code:
    class out_of_range : public logic_error {
    public:
      explicit out_of_range (const string& what_arg);
    };
    This one doesn't use throw(), but I've seen it defined with throw() in other places.

    Since it takes a string and probably converts that to a C string that the what() function will return, I don't see how it can be exception safe since c_str() isn't.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    The version listed in the C++ standard does not have an exception specification for the constructor.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Quote Originally Posted by laserlight View Post
    The version listed in the C++ standard does not have an exception specification for the constructor.
    Heh, less than 15 minutes separating the question and response. I'd say that you know the standard pretty well, Laserlight.

  4. #4
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Since it takes a string and probably converts that to a C string that the what() function will return, I don't see how it can be exception safe since c_str() isn't.
    I don't see why c_str wouldn't be exception safe. All it has to do is to return a pointer to the beginning of the internal string buffer. What might fail is storing the string (if it needs a dynamic allocation, e.g VC++ uses short string optimizations, so there shouldn't be any memory allocation for short strings).

    However, that seems like a rather theoretical problem. What are the chances that when vector.at() discovers an out-of-bounds access, you also happen to be completely out of memory?
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  5. #5
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    Quote Originally Posted by anon View Post
    I don't see why c_str wouldn't be exception safe. All it has to do is to return a pointer to the beginning of the internal string buffer. What might fail is storing the string (if it needs a dynamic allocation, e.g VC++ uses short string optimizations, so there shouldn't be any memory allocation for short strings).

    However, that seems like a rather theoretical problem. What are the chances that when vector.at() discovers an out-of-bounds access, you also happen to be completely out of memory?
    Well, it DOES have to be 0-terminated. So when you have an empty string, no space might be allocated (I can imagine), but at least 1 byte must be allocated. If this allocation fails, c_str might throw an exception.
    That's my guess at least.

  6. #6
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    c_str() may throw. So may data(), although for any given implementation this is even less likely.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  7. #7
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Quote Originally Posted by CornedBee View Post
    c_str() may throw. So may data(), although for any given implementation this is even less likely.
    How so? It just returns a pointer, after all. I would think that the only point that it could throw in that case would be inside the temporary's constructor or the member's copy constructor. I even considered that the implementation might defer allocation until there was an actual attempt to access the data, but then realized that it would have to have been initialized already since the member variable's copy constructor has to get executed. Or am I missing something?

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Sebastiani
    How so? It just returns a pointer, after all.
    A pointer to what? As of the current version of the C++ standard, there might not be an already allocated contiguous null terminated internal buffer. In such a case, some memory allocation may need to take place in order to return a pointer to the first character of such a buffer.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Quote Originally Posted by laserlight View Post
    A pointer to what? As of the current version of the C++ standard, there might not be an already allocated contiguous null terminated internal buffer. In such a case, some memory allocation may need to take place in order to return a pointer to the first character of such a buffer.
    But the string's copy constructor is guaranteed to be called in this case (AFAIK the exception classes don't have a default constructor), isn't it?

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Sebastiani
    But the string's copy constructor is guaranteed to be called in this case
    I do not see the significance of that concerning whether c_str() might throw an exception. Suppose c_str() needs to add a null terminator, and there happens to be insufficient space to do so. It does not matter that the copy constructor has been invoked; one must still allocate space. In a more extreme case, suppose that the internal buffer(s) is (are) not contiguous.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #11
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Quote Originally Posted by laserlight View Post
    I do not see the significance of that concerning whether c_str() might throw an exception. Suppose c_str() needs to add a null terminator, and there happens to be insufficient space to do so. It does not matter that the copy constructor has been invoked; one must still allocate space. In a more extreme case, suppose that the internal buffer(s) is (are) not contiguous.
    Well then why is c_str declared const? It seems unlikely to me that the implementer would violate const-correctness just to do some obscure and unorthodox buffer adjustment.

  12. #12
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Sebastiani
    Well then why is c_str declared const? It seems unlikely to me that the implementer would violate const-correctness just to do some obscure and unorthodox buffer adjustment.
    How is const correctness violated? Either way, the observable state of the string object remains the same.

    EDIT:
    Quote Originally Posted by C++03 Section 21.3 Paragraph 5
    References, pointers, and iterators referring to the elements of a basic_string sequence may be invalidated by the following uses of that basic_string object:
    (...)
    - Calling data() and c_str() member functions.
    So, in the current version of the C++ standard, there is the anticipation that an implementer might do more than just return a pointer in data() and c_str(). More explicitly:
    Quote Originally Posted by C++03 Section 21.3 Paragraph 6
    These rules are formulated to allow, but not require, a reference counted implementation. A reference counted implementation must have the same semantics as a non-reference counted implementation.
    Last edited by laserlight; 09-21-2009 at 04:11 AM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  13. #13
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Point is, though, something within the string object would have to change - there would have to be a const_cast buried somewhere in there for that to work.

    Don't get me wrong, there are situations where casting away constness is appropriate. I just don't think this is one of them (I mean, how hard would it be to simply allocate a single byte in the constructor, after all?).

  14. #14
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Sebastiani
    Point is, though, something within the string object would have to change
    That is true, but that is also of no concern as long as the observable state of the object does not change.

    Quote Originally Posted by Sebastiani
    there would have to be a const_cast buried somewhere in there for that to work.
    You might have forgotten about the mutable keyword.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  15. #15
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Quote Originally Posted by laserlight View Post
    That is true, but that is also of no concern as long as the observable state of the object does not change.

    You might have forgotten about the mutable keyword.
    I thought of that, but you responded before I had a chance to edit the post.

    A few years back, I was going through an implementation of basic_string (RogueWave's, I think) and it used such a reference-counting system, though I'm almost certain it only made copies when referencing non-const functions.

    Anyway, clearly this is a bad design, and I'm a bit shocked that the standards commitee decided to go that route. There's just no good reason to postpone the initialization of an object into a stable, usable state. It's counterintuitive and it really just creates unnecessary complications.

    My suggestion to the OP would be to just make sure that their implementation doesn't heed to such nonsense.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Exceptions that should terminate. Really.
    By Mario F. in forum C++ Programming
    Replies: 7
    Last Post: 06-26-2007, 10:56 AM
  2. include question
    By Wanted420 in forum C++ Programming
    Replies: 8
    Last Post: 10-17-2003, 03:49 AM
  3. C/C++ standard
    By confuted in forum A Brief History of Cprogramming.com
    Replies: 3
    Last Post: 07-06-2003, 03:22 AM
  4. Internal Exceptions in a BCB DLL?
    By andy668 in forum Windows Programming
    Replies: 3
    Last Post: 01-07-2002, 10:50 AM
  5. Why throw exceptions?
    By Brown Drake in forum C++ Programming
    Replies: 2
    Last Post: 11-02-2001, 06:24 PM