Thread: string operation and related exception

  1. #1
    Registered User
    Join Date
    May 2006
    Posts
    1,579

    string operation and related exception

    Hello everyone,


    I made some self-study of the possible exception from string operations. I want to let you review whether I am correct. Since I can not find any exception information from MSDN. Talking in Visual Studio STL environment is ok.

    1. assignment, may throw bad_alloc?
    2. comparison (compare), nothrow?
    3. insert, may throw bad_alloc?
    4. concatenation, may throw bad_alloc?
    5. replace, may throw bad_alloc (suppose replace small sub-string to large sub-string)?
    6. find (e.g. find_first_of), nothrow?
    7. substr, may throw bad_alloc (sub-string is something new)?


    thanks in advance,
    George

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    I think you will also potentially get other exceptions, e.g. out of range errors when trying to use indexes that are beyond the size of the string, including [but not limited to] the operator[] and substr().

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    operator[] won't throw, but at() will. So will a few others.

    The full set of exceptions is implementation-defined. Any implementation may throw whatever it wants, as long as it documents it. If MS doesn't fully document their possible exceptions, that's a documentation bug on their part.

    Edit: Actually, [] can throw since out-of-bounds is undefined behaviour, but there's no point in relying on it, and no known implementation does it.
    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

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Those versions of the member functions assign(), insert(), erase() and replace() that allow one to specify the position can throw an out_of_range exception. The member functions at(), copy() and substr() also can throw an out_of_range exception. Both versions of operator[] do not throw any exceptions.
    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

  5. #5
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Thanks CornedBee,


    Why operator[] behaves different from at(), in my knowledge operator[] could be implemented through at(), and vice versa, so why they are different?

    Quote Originally Posted by CornedBee View Post
    operator[] won't throw, but at() will. So will a few others.

    Thanks laserlight,

    Why operator[] will not throw out_of_range exception for string class if we input an invalid index value -- e.g. larger than string length?

    Quote Originally Posted by laserlight View Post
    Those versions of the member functions assign(), insert(), erase() and replace() that allow one to specify the position can throw an out_of_range exception. The member functions at(), copy() and substr() also can throw an out_of_range exception. Both versions of operator[] do not throw any exceptions.

    regards,
    George

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Why operator[] behaves different from at(), in my knowledge operator[] could be implemented through at(), and vice versa, so why they are different?

    Why operator[] will not throw out_of_range exception for string class if we input an invalid index value -- e.g. larger than string length?
    The C++ Standard requires at() to throw std::out_of_range for an invalid index, but makes no such requirement for operator[].
    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

  7. #7
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  8. #8
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Thanks laserlight and dwks,


    I think the answer to the difference between at() and operator[] is -- specification requirement.

    1. Spec requires at() to throw out of range exception;
    2. Spec does not requires operator[] to throw exception, so undefined behavior is defined.

    Right?

    Quote Originally Posted by dwks View Post

    regards,
    George

  9. #9
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Yep, that's what it says. And which I find kind of stupid. Either is throws or it doesn't. One implementation that does not check might be useful if you need raw speed, but the standard does not require the operator [] not to throw, so it might check and throw. The at() function will check and throw, that much we know.

    And surely there are better ways for an implementation not to check for out of bounds rather than let the operator not do it and the member function do it. I find it silly that I would not have the extra security simply because I'm using the operator and not a member function.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  10. #10
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    It's consistent with C syntax, and the expectation is that all implementations, in release mode, are also consistent with C, i.e. they simply allow the out-of-bounds access.
    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

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Poor design choice, if you ask me. Vector is not a C array, and let it be so.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #12
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    *shrug*

    I have no issues with this design choice.

    Out of curiosity, what would you have done?
    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

  13. #13
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I think either I would allow a flag to be set (EnableExceptions) or differentiate two types (perhaps just different names for initializing a constructor in different ways.
    vector(bool bEnableExceptions = false)
    #define SafeVector vector(true)
    Or something like that. It describes the point anyway.
    I would expect the operator [] and the member function at both to throw exceptions if exceptions are enabled. Otherwise if they aren't enabled, none should throw (or make out of bounds checks).
    I understand they want to keep C compability, but then you would be using a C array and not std::vector since that wouldn't even compile under C so not C project would ever use std::vector.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  14. #14
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    You don't gain anything from a runtime flag. The point is that operator[] has zero overhead in release mode. Any index test destroys that very thoroughly, by introducing not only additional instructions, but a branch. So any index test must be debug-only if it exists. Which is why implementations have an assert().

    C compatibility goes beyond being able to compile C++ code as C or stuff like that. Actually, it has nothing to do with that.

    C compatibility consists of two parts. One is being able to compile C code as C++ in order to reuse existing code. That part is irrelevant here, because vector is a class template.

    The other part is equally important: C programmers should be able to reuse their knowledge. If I tell a C programmer, "here's a dynamic array called vector, put the type between <> and it takes over all dynamic allocation for you", then the C programmer will want to use [] on the thing.
    Last edited by CornedBee; 02-27-2008 at 10:26 AM.
    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

  15. #15
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Yes, which is why I like a choice. I don't like the idea that just because I use the index operator instead of at(), I forgo any such out of bounds checks. If at does it, then the index operator should too.
    And that's why I also suggested a way to actually decide if the class should do out of bounds checks or not to allow for faster code.

    But from what I understand, there is no requirement by the standard that the index operator should not throw an exception. So it might throw an exception is some implementations, which is bad, as well. The standard should clearly state that the index operator, in such case, should not throw an exception at all. It should not have any out of bounds checking. It should not be undefined behavior. It should be defined behavior.
    Last edited by Elysia; 02-27-2008 at 10:30 AM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 16
    Last Post: 11-23-2007, 01:48 PM
  2. Looking for examples for string related programs
    By koloth in forum C Programming
    Replies: 5
    Last Post: 04-14-2003, 11:57 PM