Topic: STL and EXCEPTIONS
Author: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1997/06/09 Raw View
Christopher Eltschka <celtschk@physik.tu-muenchen.de> writes:
|> Paul D. DeRocco wrote:
|> >
|> > James Kanze wrote:
|> > >
|> > > What do you mean? Most implementations don't do range checking with
|> > > regular pointers, but it is certainly allowed (and I think that
|> > > CenterLine actually had an implementation once which did it).
|> >
|> > The only way I can imagine an implementation doing range checking on
|> > plain pointers is on something like an x86 CPU in protected mode, with
|> > every object being mapped by an OS call into a separate segment with
|> > hardware range checking. (Actually, the old Intel 432 attempted this
|> > kind of fine-grain hardware protection, but it was waaay too slow.) An
|> > array might be associated with a length somehow, but a pointer can point
|> > into the middle of an array, and I don't see how you can find out the
|> > length of the original array from that pointer. The standard might not
|> > prohibit such an implementation, but it also doesn't prohibit lots of
|> > nice but impossible things.
|>
|> But it isn't impossible. You can hold a complete list of all existing
|> objects and arrays (registering/deregistering of objects can be done
|> by constructor/destructor calls, registering/deregistering of dynamic
|> memory can be done from allocation/deallocation calls). Then if you
|> have a pointer to anywhere, you can look up the memory area which it
|> points to in the table, and this way detect the beginning/end of the
|> array. There are some other points to look at (pointer arithmetics,
|> f. ex.), but it works (there exists a patch for GNU C working this way,
|> by *adding* transparent constructors/destructors - a non-C concept,
|> of course - to the C types, and replacing pointer operations with
|> own versions.)
|> This way, you could even add and check arbitrary information (exact
|> type layout, f.ex.) without any problems (except for speed, of course).
An even simpler solution (to implement): pointers can be an arbitrary
size (including larger than any integral type), so use something like
the following instead of the native pointer:
struct
{
void* base ; // physical pointer
size_t offset ;
size_t maxOffset ;
} ;
Again, you pay a serious price in performance, probably too much to
allow something like this to be used in production code. But it is
certainly legal, and would be quite useful for debugging purposes.
--
James Kanze home: kanze@gabi-soft.fr +33 (0)1 39 55 85 62
office: kanze@vx.cit.alcatel.fr +33 (0)1 69 63 14 54
GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles France
-- Conseils en informatique industrielle --
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1997/06/02 Raw View
Paul D. DeRocco wrote:
>
> James Kanze wrote:
> >
> > What do you mean? Most implementations don't do range checking with
> > regular pointers, but it is certainly allowed (and I think that
> > CenterLine actually had an implementation once which did it).
>
> The only way I can imagine an implementation doing range checking on
> plain pointers is on something like an x86 CPU in protected mode, with
> every object being mapped by an OS call into a separate segment with
> hardware range checking. (Actually, the old Intel 432 attempted this
> kind of fine-grain hardware protection, but it was waaay too slow.) An
> array might be associated with a length somehow, but a pointer can point
> into the middle of an array, and I don't see how you can find out the
> length of the original array from that pointer. The standard might not
> prohibit such an implementation, but it also doesn't prohibit lots of
> nice but impossible things.
But it isn't impossible. You can hold a complete list of all existing
objects and arrays (registering/deregistering of objects can be done
by constructor/destructor calls, registering/deregistering of dynamic
memory can be done from allocation/deallocation calls). Then if you
have a pointer to anywhere, you can look up the memory area which it
points to in the table, and this way detect the beginning/end of the
array. There are some other points to look at (pointer arithmetics,
f. ex.), but it works (there exists a patch for GNU C working this way,
by *adding* transparent constructors/destructors - a non-C concept,
of course - to the C types, and replacing pointer operations with
own versions.)
This way, you could even add and check arbitrary information (exact
type layout, f.ex.) without any problems (except for speed, of course).
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1997/05/22 Raw View
"Paul D. DeRocco" <strip_these_words_pderocco@ix.netcom.com> writes:
|> James Kanze wrote:
|> >
|> > What do you mean? Most implementations don't do range checking with
|> > regular pointers, but it is certainly allowed (and I think that
|> > CenterLine actually had an implementation once which did it).
|>
|> The only way I can imagine an implementation doing range checking on
|> plain pointers is on something like an x86 CPU in protected mode, with
|> every object being mapped by an OS call into a separate segment with
|> hardware range checking. (Actually, the old Intel 432 attempted this
|> kind of fine-grain hardware protection, but it was waaay too slow.) An
|> array might be associated with a length somehow, but a pointer can point
|> into the middle of an array, and I don't see how you can find out the
|> length of the original array from that pointer. The standard might not
|> prohibit such an implementation, but it also doesn't prohibit lots of
|> nice but impossible things.
In fact, I think that the implementation uses "fat" pointers; the
pointer carries the necessary bounds information with it. Thus, the
actual pointer might be the physical equivalent of:
struct
{
void* base ;
size_t offset ;
size_t maxOffset ;
} ;
Pointer arithmetic is on the offset.
The obvious reason why such implementations aren't the standard is that
the performance penalty for typical code (which passes pointers around
all over the place) is very high. And of course, *every* module must
use this implementation, including the libraries.
--
James Kanze home: kanze@gabi-soft.fr +33 (0)1 39 55 85 62
office: kanze@vx.cit.alcatel.fr +33 (0)1 69 63 14 54
GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles France
-- Conseils en informatique industrielle --
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: "Paul D. DeRocco" <strip_these_words_pderocco@ix.netcom.com>
Date: 1997/05/20 Raw View
James Kanze wrote:
>
> What do you mean? Most implementations don't do range checking with
> regular pointers, but it is certainly allowed (and I think that
> CenterLine actually had an implementation once which did it).
The only way I can imagine an implementation doing range checking on
plain pointers is on something like an x86 CPU in protected mode, with
every object being mapped by an OS call into a separate segment with
hardware range checking. (Actually, the old Intel 432 attempted this
kind of fine-grain hardware protection, but it was waaay too slow.) An
array might be associated with a length somehow, but a pointer can point
into the middle of an array, and I don't see how you can find out the
length of the original array from that pointer. The standard might not
prohibit such an implementation, but it also doesn't prohibit lots of
nice but impossible things.
--
Ciao,
Paul
(Please remove the "strip_these_words_" prefix from the return
address, which has been altered to foil junk mail senders.)
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1997/05/17 Raw View
"Paul D. DeRocco" <strip_these_words_pderocco@ix.netcom.com> writes:
|> James Kanze wrote:
|> >
|> > More correctly: the operator[] isn't required to do complete range
|> > checking, because the standards committee defined it that way,
|> > presumably in order to give implementations a maximum of freedom in the
|> > implementation.
|>
|> I think the main reason is to be consistent with regular pointers, on
|> which operator[] can't do range checking.
What do you mean? Most implementations don't do range checking with
regular pointers, but it is certainly allowed (and I think that
CenterLine actually had an implementation once which did it).
--
James Kanze home: kanze@gabi-soft.fr +33 (0)1 39 55 85 62
office: kanze@vx.cit.alcatel.fr +33 (0)1 69 63 14 54
GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles France
-- Conseils en informatique industrielle --
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1997/05/14 Raw View
Matt Austern <austern@sgi.com> writes:
|> cstraka@aixterm1.urz.uni-heidelberg.de (Christian Straka) writes:
|>
|> > Why doesn't the index operator "operator[]()" throw any exceptions?
|> >
|> > I want to do the following:
|> >
|> > vector<int> vec(3);
|> > int a:
|> > try{
|> > a = vec[4]; does not throw ...
|> > }catch(..){
|> > // ... and never reaches this code
|> > }
|> >
|> > As I want to do range checking I first thought of overloading operator[], but this function is not made virtual by its implementators!
|> >
|> > How can one solve the problem of range checking with the STL if exceptions are not properly implemented and the functions that need to be overloaded are not made virtual?
|>
|> Operator[] doesn't do range checking because range checking is
|> expensive.
More correctly: the operator[] isn't required to do complete range
checking, because the standards committee defined it that way,
presumably in order to give implementations a maximum of freedom in the
implementation.
The standard certainly allows range checking with operator[], and I
would imagine that any reasonable implementation will offer a version
which does for debugging purposes, if nothing else. Note that the
implementation (but not the user) can freely violate the ODR if it
wishes, and make the presense or absense of range checking depend on
e.g. the state of the NDEBUG macro at the call site. (This would, of
course, require some special compiler magic. Making it depend on the
state of NDEBUG at the site of #include <string>, however, would be
trivial for most implementations, and would probably be almost as
useful.)
Finally, the const version will normally require some range checking,
since it has a defined results for the index one past the end of the
string (returns a const_reference to the end of string character).
|> The draft standard does, however, include a member function called
|> "at". It does just the same thing as operator[], except that it
|> throws an exception if its argument is out of range.
IMHO: they inversed them. My own (pre-standard) versions had range
checking in operator[], and a function unsafeAt without the range
checking, on the grounds that you normally want the range checking,
except where profiling shows it a problem.
--
James Kanze home: kanze@gabi-soft.fr +33 (0)1 39 55 85 62
office: kanze@vx.cit.alcatel.fr +33 (0)1 69 63 14 54
GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles France
-- Conseils en informatique industrielle --
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: "Paul D. DeRocco" <strip_these_words_pderocco@ix.netcom.com>
Date: 1997/05/14 Raw View
James Kanze wrote:
>
> More correctly: the operator[] isn't required to do complete range
> checking, because the standards committee defined it that way,
> presumably in order to give implementations a maximum of freedom in the
> implementation.
I think the main reason is to be consistent with regular pointers, on
which operator[] can't do range checking.
--
Ciao,
Paul
(Please remove the "strip_these_words_" prefix from the return
address, which has been altered to foil junk mail senders.)
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/05/06 Raw View
cstraka@aixterm1.urz.uni-heidelberg.de (Christian Straka) writes:
>Why doesn't the index operator "operator[]()" throw any exceptions?
Checking array bounds would be costly, and sometimes you don't
want to pay that cost. Furthermore C has a tradition of not checking
for these things by default.
That said, you can get a version of STL that checks for problems like
this at <http://www.horstmann.com/safestl.html>.
--
Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3 | -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Oleg Zabluda <zabluda@math.psu.edu>
Date: 1997/05/06 Raw View
Christian Straka <cstraka@aixterm1.urz.uni-heidelberg.de> wrote:
: Why doesn't the index operator "operator[]()" throw any exceptions?
: I want to do the following:
: vector<int> vec(3);
: int a:
: try{
: a = vec[4]; does not throw ...
: }catch(..){
: // ... and never reaches this code
: }
Use vec.at(4). It will throw out_of_range.
Oleg.
--
Life is a sexually transmitted, 100% lethal disease.
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Kresimir Fresl <fresl@grad.hr>
Date: 1997/05/06 Raw View
Christian Straka wrote:
> Why doesn't the index operator "operator[]()" throw
> any exceptions?
CD2 in chapter 23 `Containers library', section
23.1.1 `Sequences', table 6 `Optional sequence operations'
defines vector and deque member functions at() whose
operational semantics is the same as for operator[], but
clause 10 says:
``The member function at() provides bounds-checked
access to container elements. at() throws out_of_range
if n >= a.size().''
> I am using a STL implementation from Rouge Wave which
> is shipped with the Borland Compilers.
Unfortunately, if there is no member function at(), you
should wait for newer version.
> How can one solve the problem of range checking with the STL
> if exceptions are not properly implemented and the functions
> that need to be overloaded are not made virtual?
Overloading and inheritance are two different concepts. But
if you mean what I think you do, as far as you do not access
your class (derived from vector) through pointer or reference
to base class (vector), you can ``overload'' operator[].
fres
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Matt Austern <austern@sgi.com>
Date: 1997/05/06 Raw View
cstraka@aixterm1.urz.uni-heidelberg.de (Christian Straka) writes:
> Why doesn't the index operator "operator[]()" throw any exceptions?
>
> I want to do the following:
>
> vector<int> vec(3);
> int a:
> try{
> a = vec[4]; does not throw ...
> }catch(..){
> // ... and never reaches this code
> }
>
> As I want to do range checking I first thought of overloading operator[], but this function is not made virtual by its implementators!
>
> How can one solve the problem of range checking with the STL if exceptions are not properly implemented and the functions that need to be overloaded are not made virtual?
Operator[] doesn't do range checking because range checking is
expensive.
The draft standard does, however, include a member function called
"at". It does just the same thing as operator[], except that it
throws an exception if its argument is out of range.
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: cstraka@aixterm1.urz.uni-heidelberg.de (Christian Straka)
Date: 1997/05/06 Raw View
Why doesn't the index operator "operator[]()" throw any exceptions?
I want to do the following:
vector<int> vec(3);
int a:
try{
a = vec[4]; does not throw ...
}catch(..){
// ... and never reaches this code
}
As I want to do range checking I first thought of overloading operator[], but this function is not made virtual by its implementators!
How can one solve the problem of range checking with the STL if exceptions are not properly implemented and the functions that need to be overloaded are not made virtual?
I am using a STL implementation from Rouge Wave which is shipped with the Borland Compilers.
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]