Thread: string operation and related exception

Hybrid View

Previous Post Previous Post   Next Post Next Post
  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
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Hi CornedBee,


    Here is the current implementation of STL vector from Visual Studio 2008. Looks like for operator[], both release and debug version checks for boundary. So how about your points of performance improvements and speed? Any comments?

    Code:
    #if !defined (_HAS_ITERATOR_DEBUGGING)
    	#if defined (_DEBUG)
    		#define _HAS_ITERATOR_DEBUGGING	1	/* for range checks, etc. */
    	#else
    		#define _HAS_ITERATOR_DEBUGGING	0
    	#endif	/* defined (_DEBUG) */
    #else
    
    	reference operator[](size_type _Pos)
    		{	// subscript mutable sequence
    
     #if _HAS_ITERATOR_DEBUGGING
    		if (size() <= _Pos)
    			{
    			_DEBUG_ERROR("vector subscript out of range");
    			_SCL_SECURE_OUT_OF_RANGE;
    			}
     #endif /* _HAS_ITERATOR_DEBUGGING */
    		_SCL_SECURE_VALIDATE_RANGE(_Pos < size());
    
    		return (*(_Myfirst + _Pos));
    		}
    
    
    
    
    	reference at(size_type _Pos)
    		{	// subscript mutable sequence with checking
    		if (size() <= _Pos)
    			_Xran();
    		return (*(begin() + _Pos));
    		}
    
    
    	static void _Xran()
    		{	// report an out_of_range error
    		_THROW(out_of_range, "invalid vector<T> subscript");
    		}
    Quote Originally Posted by CornedBee View Post
    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.

    regards,
    George

  12. #12
    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.

  13. #13
    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

  14. #14
    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.

  15. #15
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by Elysia View Post
    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.
    A flag sucks because somebody has to set it, and you never know which way it was set by the person before you.

    vector(bool bEnableExceptions = false)
    So now I have to specify a fundamental design decision (whether the operator[] does bounds checks) every time I declare a vector?

    #define SafeVector vector(true)
    I literally barfed on that one..

    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 expect cars to have seven cylinders, and be built entirely of fiberglass.

    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.
    Why would I want to give up all the conveniences of a std::vector and go back to dumb arrays just because I don't want bounds checking?

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