Copyright (c) 1994 Hewlett-Packard Company
That material is provided pursuant to the following permission notice.
Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. Hewlett-Packard Company makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty.
The Safe STL enhancements are
(C) Horstmann Software Design Corp. 1995. All Rights Reserved.
You may freely use, copy, modify, or distribute these Safe STL enhancements and this documentation for any purpose, provided (1) you charge NO FEE for distributing these copyrighted materials and (2) you include both the copyright notice and permission notice from Hewlett-Packard Company and this copyright notice and permission notice. Horstmann Software Design Corporation specifically disclaims that these materials might do anything useful at all. If they work for you and don't destroy anything, you are in luck. There is no free technical support available for these materials.
If an error is detected, then an assertion failure is raised. (See section 6 to see how to change that behavior.)
Of course, checking and updating the iterators takes time. For release versions of your code, you would probably want to go back to the unchecked version of STL.
The interface of Safe STL is purposefully left the same as that of regular STL. It would be an easy matter to add public member functions to the iterators that check their status, but I believe that it is best not to develop yet another nonstandard template library.
Safe STL works better than a debugger or BoundsChecker for a number of reasons. If your code dies because of a pointer error that is the consequence of an STL usage error, the debugger will break deep in the bowels of STL code which is usually less than illuminating. If your code gets in an infinite loop because of an STL usage error, BoundsChecker will not actually complain. Some STL usage errors cause subtle inconsistencies in the STL data structures that will not lead to immediate failure. See the examples in section 4 for more information.
listThis code will loop forever when a.end() is reached.a; list b; // ... list ::iterator p = find(a.begin(), b.end(), 100); // oops, should have been a.end() if (p != a.end()) a.erase(p);
Of course nobody would make such a dumb coding mistake.
I did several times, when I did some cut and paste and was sloppy about updating the pasted code.
listIn the HP implementation, this will erase the first element of a, but reduce the length of b! Eventually, but not immediately, that will lead to weird behavior.a; list b; list ::iterator pa = a.begin(); b.erase(pa);
list::iterator p = find_if(a.begin(), a.end(), condition); cout << *p; // an error if p is past the end
list::iterator p; cout << *p; // an error
list::iterator p = a.begin(); list ::iterator q = p; a.erase(q); cout << *p; // an error
vector::iterator p = b.begin(); b.reserve(1000); cout << *p; // maybe an error
list* pl = new list ; list ::iterator p = pl->begin(); delete pl; cout << *p; // an error
algobase.h vector.h deque.h list.h tree.hinto a separate directory, e.g. /safestl. Then put that directory into the directory search path, BEFORE the directory that contains the regular STL. For example,
bcc -I/safestl;/stl whatnot.cppThen compile and link your application.
Note: You must rebuild the ENTIRE application. You cannot have mixed object files that share STL containers and iterators, some compiled with the regular and others with the safe headers. I realize that may be impossible if some of your code is compiled into libraries whose interface references an STL container or iterator.
Once your application is debugged, simply remove /safestl from the include path and rebuild the application.
You will notice that Safe STL generates a large number of WARNINGS. Unfortunately, there is little I can do about that without modifying the original STL source extensively. Some warnings come from int/unsigned mismatches--they also occur in regular STL. Others have the form "functions with property X cannot be inline expanded". I don't want them inline expanded, but I have no choice--the Borland compiler does not support templates defining member functions of nested classes. If the Safe STL code becomes popular, I may rewrite it to eliminate most warnings, but deviating further from the regular STL code.
Why didn't I throw an exception when detecting a failure? That would have changed the interface of the STL classes, which I didn't want to do. Had the operations thrown exceptions upon failure, then you might write code catching them. That code would no longer work when you switch back to regular STL.
However, there is one major disadvantage to using assert. The debugger will not give you a stack trace at the point of failure, so you can't see what part of your code caused the problem. (The file and line number reported by assert are in the Safe STL header.) If your debugger can break on exception throw (like Turbo Debugger), you can view the stack and locate the offending code. A brutal but effective way is to turn the assertion failure into an exception. Before including the Safe STL headers,
#define assert(X) if (!(X)) throw #X;After the Safe STL headers, undefine it again.
PLEASE, NO REQUESTS FOR HANDHOLDING. If you can't compile the sample programs of the HP ftp site with regular and safe STL, or you don't know how to set up the files and the compiler, then I cannot and will not try to fix it for you.
I am particular interested in