Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

NDEBUG for range checks?

5 views
Skip to first unread message

Bill Godfrey

unread,
Apr 22, 2002, 10:17:01 AM4/22/02
to
It was with much surprise that I read that for vectors, operator[]()
will not range check, but at() will.

Maybe I've been a C programmer for too long, but why not use assert()
within both to range check?

That way, no change for debugging, and -DNDEBUG for released code.

Bill, been a C programmer for too long.

--
Experienced (5yrs) C/C++/Embedded programmer seeking work
in the English midlands.
http://www.bacchae.co.uk/cv/

Alwyn

unread,
Apr 22, 2002, 10:21:42 AM4/22/02
to
In article <i2pu1q3...@cvhf434.gpt.co.uk>,
Bill Godfrey <billg-...@bacchae.f9.co.uk.invalid> wrote:

> It was with much surprise that I read that for vectors, operator[]()
> will not range check, but at() will.
>
> Maybe I've been a C programmer for too long, but why not use assert()
> within both to range check?
>
> That way, no change for debugging, and -DNDEBUG for released code.

But having range checks in released code is a good thing too. Think of
all those security expoits involving buffer overruns.

If you want the range checks for safety, you can use 'at'; if you want
to bypass them for the sake of speed, use '[]'. That seems like a
close-to-ideal solution to me.


Alwyn

Bill Godfrey

unread,
Apr 22, 2002, 10:49:27 AM4/22/02
to
Alwyn <al...@alwyn.demon.co.uk> writes:

> But having range checks in released code is a good thing too. Think of
> all those security expoits involving buffer overruns.

Then leave NDEBUG switched on.



> If you want the range checks for safety, you can use 'at'; if you want
> to bypass them for the sake of speed, use '[]'. That seems like a
> close-to-ideal solution to me.

If you change your mind, replacing [] with at() is difficult, compared
to pre-processor play.

I must admit, the main reason for my annoyance was that I wrote a load of
code with [], later realising that there would be no error checks.

So I hacked in an assert into the header file.

Why not?

Bill, "No range checks? Wasn't this the whole point of vector?"

Neil Butterworth

unread,
Apr 22, 2002, 10:57:24 AM4/22/02
to
"Bill Godfrey" <billg-...@bacchae.f9.co.uk.invalid> wrote in message
news:i2pr8l7...@cvhf434.gpt.co.uk...

> Alwyn <al...@alwyn.demon.co.uk> writes:
>
> > But having range checks in released code is a good thing too. Think of
> > all those security expoits involving buffer overruns.
>
> Then leave NDEBUG switched on.
>
> > If you want the range checks for safety, you can use 'at'; if you want
> > to bypass them for the sake of speed, use '[]'. That seems like a
> > close-to-ideal solution to me.
>
> If you change your mind, replacing [] with at() is difficult, compared
> to pre-processor play.
>
> I must admit, the main reason for my annoyance was that I wrote a load of
> code with [], later realising that there would be no error checks.
>
> So I hacked in an assert into the header file.
>
> Why not?
>
> Bill, "No range checks? Wasn't this the whole point of vector?"

I can't see the point of range checks on a vector myself. You are either
stepping through the thing with an iterator or using an index which you
compare against the vector's size() member. In either case, how can you have
an out of range error? And if you do get one, how are you going to recover
from it?

NeilB


Alwyn

unread,
Apr 22, 2002, 11:06:04 AM4/22/02
to
In article <3cc42476$1...@mk-nntp-1.news.uk.worldonline.com>,

"Neil Butterworth" <neil_but...@lineone.net> wrote:
>
> I can't see the point of range checks on a vector myself. You are either
> stepping through the thing with an iterator or using an index which you
> compare against the vector's size() member. In either case, how can you have
> an out of range error? And if you do get one, how are you going to recover
> from it?

Well, once you step out of range, an exception is thrown, and the
current operation is terminated. This does not necessarily mean that the
program itself is terminated; it can begin a new operation after the
exception is caught.

This would at the very least prevent the many security exploits that
depend on buffer overruns for their effectiveness.


Alwyn

Alwyn

unread,
Apr 22, 2002, 11:09:35 AM4/22/02
to
In article <i2pr8l7...@cvhf434.gpt.co.uk>,
Bill Godfrey <billg-...@bacchae.f9.co.uk.invalid> wrote:

> Alwyn <al...@alwyn.demon.co.uk> writes:
>
> > But having range checks in released code is a good thing too. Think of
> > all those security expoits involving buffer overruns.
>
> Then leave NDEBUG switched on.
>
> > If you want the range checks for safety, you can use 'at'; if you want
> > to bypass them for the sake of speed, use '[]'. That seems like a
> > close-to-ideal solution to me.
>
> If you change your mind, replacing [] with at() is difficult, compared
> to pre-processor play.
>
> I must admit, the main reason for my annoyance was that I wrote a load of
> code with [], later realising that there would be no error checks.
>
> So I hacked in an assert into the header file.
>
> Why not?

But a failed 'assert' will terminate your program, won't it? Many of the
programs I used to work on could not afford to terminate; they were
expected to run 24/7. You catch the exception, report the error, abandon
the current operation and proceed to the next one.


Alwyn

Neil Butterworth

unread,
Apr 22, 2002, 11:19:31 AM4/22/02
to
"Alwyn" <al...@alwyn.demon.co.uk> wrote in message
news:alwyn-551A22....@news-text.blueyonder.co.uk...

> In article <3cc42476$1...@mk-nntp-1.news.uk.worldonline.com>,
> "Neil Butterworth" <neil_but...@lineone.net> wrote:
> >
> > I can't see the point of range checks on a vector myself. You are either
> > stepping through the thing with an iterator or using an index which you
> > compare against the vector's size() member. In either case, how can you
have
> > an out of range error? And if you do get one, how are you going to
recover
> > from it?
>
> Well, once you step out of range, an exception is thrown, and the
> current operation is terminated. This does not necessarily mean that the
> program itself is terminated; it can begin a new operation after the
> exception is caught.

Of course, but assuming that you were using an iterator or an index checked
against size(), what does an out-of-range exception mean? You can of course
catch the exception, but I don't see how you can recover.

> This would at the very least prevent the many security exploits that
> depend on buffer overruns for their effectiveness.

Yes, but my point is I don't see haw a buffer overrun can happen if you
write your code correctly. The se exploits are really not exploiting buffer
overruns per se, but are exploiting badly written code.

NeilB


Alwyn

unread,
Apr 22, 2002, 11:20:52 AM4/22/02
to
In article <3cc429a6$1...@mk-nntp-1.news.uk.worldonline.com>,

Well, as long as you have programmers, you will have badly written code.
:-)

Given the truth of the above, isn't it sensible to provide some
safeguards at run-time?


Alwyn

Alwyn

unread,
Apr 22, 2002, 11:25:56 AM4/22/02
to
In article <3cc429a6$1...@mk-nntp-1.news.uk.worldonline.com>,
"Neil Butterworth" <neil_but...@lineone.net> wrote:

> "Alwyn" <al...@alwyn.demon.co.uk> wrote in message
> news:alwyn-551A22....@news-text.blueyonder.co.uk...
> > In article <3cc42476$1...@mk-nntp-1.news.uk.worldonline.com>,
> > "Neil Butterworth" <neil_but...@lineone.net> wrote:
> > >
> > > I can't see the point of range checks on a vector myself. You are either
> > > stepping through the thing with an iterator or using an index which you
> > > compare against the vector's size() member. In either case, how can you
> have
> > > an out of range error? And if you do get one, how are you going to
> recover
> > > from it?
> >
> > Well, once you step out of range, an exception is thrown, and the
> > current operation is terminated. This does not necessarily mean that the
> > program itself is terminated; it can begin a new operation after the
> > exception is caught.
>
> Of course, but assuming that you were using an iterator or an index checked
> against size(), what does an out-of-range exception mean? You can of course
> catch the exception, but I don't see how you can recover.

For one thing, it's very easy in the STL to check against an iterator to
the wrong container or the size of another container. I believe there is
a 'safe' version of the STL available that can check against the former
case.


Alwyn

Neil Butterworth

unread,
Apr 22, 2002, 11:31:23 AM4/22/02
to
"Alwyn" <al...@alwyn.demon.co.uk> wrote in message
news:alwyn-5D60B8....@news-text.blueyonder.co.uk...

It would be impossible to guard against this using an assert() (after all,
you'd probably make the same error in the assertion) so I guess using at()
is the only way to go if you want range checking, at least for vectors.

NeilB


Alexander Terekhov

unread,
Apr 22, 2002, 12:05:58 PM4/22/02
to
Alwyn wrote:
[...]

> But a failed 'assert' will terminate your program, won't it? Many of the
> programs I used to work on could not afford to terminate; they were
> expected to run 24/7. You catch the exception, report the error, abandon
> the current operation and proceed to the next one.

And... transfer $1.000.000 or so to *MY* account ("accidentally"/due
to corrupted program state) -- GOOD! ;-) Or do something like that;
hopefully "good" kind of thing.

Or are you saying that your programs are *specifically* designed
to produce out-of-range-like errors from time to time? How about
SIGSEGV-like traps/exceptions? Why not catch/ignore this sort
of things as well?!

regards,
alexander.

Alwyn

unread,
Apr 22, 2002, 12:24:30 PM4/22/02
to
In article <3CC434E6...@web.de>,
Alexander Terekhov <tere...@web.de> wrote:

> Alwyn wrote:
> [...]
> > But a failed 'assert' will terminate your program, won't it? Many of the
> > programs I used to work on could not afford to terminate; they were
> > expected to run 24/7. You catch the exception, report the error, abandon
> > the current operation and proceed to the next one.
>
> And... transfer $1.000.000 or so to *MY* account ("accidentally"/due
> to corrupted program state) -- GOOD! ;-) Or do something like that;
> hopefully "good" kind of thing.

Terekhov, you can be so funny!

I always thought range checks which caused exceptions to be raised was a
reasonable way of avoiding permanent corruptions of program state.

> Or are you saying that your programs are *specifically* designed
> to produce out-of-range-like errors from time to time? How about
> SIGSEGV-like traps/exceptions? Why not catch/ignore this sort
> of things as well?!

That would perhaps be too much of a good thing. :-)

Actually, I once troubleshooted (is that the right verb form?) on a
billing system, which accepted batch input from a provisioning system.
Immediately a data error was encountered (the provisioning system was
notoriously prone to producing bad data), the billing run would shut
down and would have to be restarted. It took some effort to persuade the
programmer concerned that that was not a good idea. (For what it's
worth, I'll add that he was a COBOL programmer, not a C++ one.)


Alwyn

Alexander Terekhov

unread,
Apr 22, 2002, 2:20:37 PM4/22/02
to

Alwyn wrote:
>
> In article <3CC434E6...@web.de>,
> Alexander Terekhov <tere...@web.de> wrote:
>
> > Alwyn wrote:
> > [...]
> > > But a failed 'assert' will terminate your program, won't it? Many of the
> > > programs I used to work on could not afford to terminate; they were
> > > expected to run 24/7. You catch the exception, report the error, abandon
> > > the current operation and proceed to the next one.
> >
> > And... transfer $1.000.000 or so to *MY* account ("accidentally"/due
> > to corrupted program state) -- GOOD! ;-) Or do something like that;
> > hopefully "good" kind of thing.
>
> Terekhov, you can be so funny!

That's just a side effect of me trying to produce
not-so-funny programs[1]! ;-) Y'know, something
along the lines of:

FUNNY_AMOUNT( programmers_mood,program )

tends to be the const -- if/when a programmer is
in LESS funny mood... well, his program(s)... ;-)

> I always thought range checks which caused exceptions to be raised was a
> reasonable way of avoiding permanent corruptions of program state.

Sure, if you program/write something like:

try {
for ( index = 0; /* what something.size()? who cares! */; ++index ) {
/*....*/something.pos( index )/*....*/ ;
}
}
catch( const out_of_range_error& ) { // Oh! Ah! DONE!! }

If *NOT* (like me-stupid), then its likely to be
just an indication of *already corrupted program
state*/bug causing a violation of this or that
library' "requires" clause -- throw of somewhat
silly exception *no one* (usually/in his right
mind) is supposed to handle/recover from in a
REASONABLE program (a few special cases aside).
Unless, of course, you are able/smart enough to
inspect every byte/word/whatever in the "suspect"
region and "try to recover" within the program
itself -- without HOT (or WARM) restart (re-loading
the program state/objects saved/updated previously
(at the last "good" check point) but in a NEW/CLEAN
address space, for example).

> > Or are you saying that your programs are *specifically* designed
> > to produce out-of-range-like errors from time to time? How about
> > SIGSEGV-like traps/exceptions? Why not catch/ignore this sort
> > of things as well?!
>
> That would perhaps be too much of a good thing. :-)

But what's the "principle" difference? I don't see it.

> Actually, I once troubleshooted (is that the right verb form?) on a
> billing system, which accepted batch input from a provisioning system.
> Immediately a data error was encountered (the provisioning system was
> notoriously prone to producing bad data), the billing run would shut
> down and would have to be restarted. It took some effort to persuade the
> programmer concerned that that was not a good idea.

To me, good idea: *INPUT VALIDATION*! Oder? ;-)

regards,
alexander.

[1]
http://www.codeproject.com/interview/herbsutter3032002.asp?select=136813&forumid=3455&fr=102#xx136813xx
(see "(it stayed as public beta forever" bit/link; And,
Heck! that entire "LOL" thread was *real fun* too ;-) ;-))

NotFound

unread,
Apr 22, 2002, 2:30:53 PM4/22/02
to
> Yes, but my point is I don't see haw a buffer overrun can happen if you
> write your code correctly.

You can write a code that does not do checks by itself, but uses at.
This is correct.

Regards.

Fearless Freep

unread,
Apr 22, 2002, 4:25:29 PM4/22/02
to
"Neil Butterworth" <neil_but...@lineone.net> wrote in message news:<3cc42476$1...@mk-nntp-1.news.uk.worldonline.com>...

> I can't see the point of range checks on a vector myself. You are either
> stepping through the thing with an iterator or using an index which you
> compare against the vector's size() member. In either case, how can you have
> an out of range error? And if you do get one, how are you going to recover
> from it?

For sequential access, sure. For random access, especially where the
index comes from outside of your control, it helps


Take care,
Jay O'Connor
joco...@cybermesa.com

Neil Butterworth

unread,
Apr 22, 2002, 4:33:05 PM4/22/02
to
"Fearless Freep" <joco...@cybermesa.com> wrote in message
news:7d3dc526.02042...@posting.google.com...


int GetSome( const vector <int> & v, int index ) {

if ( index < 0 || index >= v.size() ) {
// handle the error
}
else {
return v[index];
}
}


Not exactly rocket science.

NeilB


Edwin Robert Tisdale

unread,
Apr 22, 2002, 4:21:29 PM4/22/02
to
Bill Godfrey wrote:

> It was with much surprise that I read that,


> for vectors, operator[]() will not range check, but at() will.
>
> Maybe I've been a C programmer for too long

> but why not use assert() within both to range check?

Because passing an out-of-range subscript to at() is NOT a bug.
The behavior of member function at() is well-defined
when the subscript is out-of-range.
It is supposed to throw an exception -- out_of_range.

Passing an out-of-range subscript to operator[]() IS a bug.
The behavior of member operator[]() is undefined
when the subscript is out-of-range.
The vector class library developer isn't required to include code
to check for out-of-range subscripts so that operator[]()
can be used in high performance applications
where it is possible to prove that the subscript cannot be out-of-range.

The vector class library developer could (and probably should)
use the assert macro or some equivalent in the implementation
of operator[]() to help application programmers detect
out-of-range subscripts during program development and testing
then turn off the error checking after testing and debugging
are complete and just before the application is deployed.

> That way, no change for debugging, and -DNDEBUG for released code.

No.
Member functions at() must ALWAYS check for out-of-range subscripts.

> Bill, been a C programmer for too long.

Not long enough.
Keep at it.
You'll get the hang of it someday.


Alwyn

unread,
Apr 22, 2002, 6:57:37 PM4/22/02
to
In article <3CC45475...@web.de>,

Alexander Terekhov <tere...@web.de> wrote:
>
> Alwyn wrote:
> >
> > In article <3CC434E6...@web.de>,
> > Alexander Terekhov <tere...@web.de> wrote:
> >
> > > Or are you saying that your programs are *specifically* designed
> > > to produce out-of-range-like errors from time to time? How about
> > > SIGSEGV-like traps/exceptions? Why not catch/ignore this sort
> > > of things as well?!
> >
> > That would perhaps be too much of a good thing. :-)
>
> But what's the "principle" difference? I don't see it.

There is no difference of principle. However, when your process has
received a SIGSEGV signal, it is best not to try to recover, in my
subjective experience. Things have gone too far.

On the other hand, catching an 'out of range' exception judiciously may
allow you to terminate the current operation and proceed with the next
one, with the reasonable expectation that it will complete normally.

> > Actually, I once troubleshooted (is that the right verb form?) on a
> > billing system, which accepted batch input from a provisioning system.
> > Immediately a data error was encountered (the provisioning system was
> > notoriously prone to producing bad data), the billing run would shut
> > down and would have to be restarted. It took some effort to persuade the
> > programmer concerned that that was not a good idea.
>
> To me, good idea: *INPUT VALIDATION*! Oder? ;-)

Nein, nein und immer nein! :-)


Alwyn

Neil Butterworth

unread,
Apr 22, 2002, 7:08:10 PM4/22/02
to
"Alwyn" <al...@alwyn.demon.co.uk> wrote in message
news:alwyn-5D70F9....@news.fu-berlin.de...

> In article <3CC45475...@web.de>,
> Alexander Terekhov <tere...@web.de> wrote:
> >
> > Alwyn wrote:
> > >
> > > In article <3CC434E6...@web.de>,
> > > Alexander Terekhov <tere...@web.de> wrote:
> > >
> > > > Or are you saying that your programs are *specifically* designed
> > > > to produce out-of-range-like errors from time to time? How about
> > > > SIGSEGV-like traps/exceptions? Why not catch/ignore this sort
> > > > of things as well?!
> > >
> > > That would perhaps be too much of a good thing. :-)
> >
> > But what's the "principle" difference? I don't see it.
>
> There is no difference of principle. However, when your process has
> received a SIGSEGV signal, it is best not to try to recover, in my
> subjective experience. Things have gone too far.
>
> On the other hand, catching an 'out of range' exception judiciously may
> allow you to terminate the current operation and proceed with the next
> one, with the reasonable expectation that it will complete normally.

To me if you get either a segment violation or a range violation it is an
indication of one thing - your code has bugs in it. I would rather terminate
processing than accumulate more errors because of those bugs.

NeilB


Alwyn

unread,
Apr 22, 2002, 7:13:02 PM4/22/02
to
In article <3cc49...@mk-nntp-1.news.uk.worldonline.com>,
"Neil Butterworth" <neil_but...@lineone.net> wrote:

Hehehe, I'm sure you can't name me a substantial program that doesn't
have bugs in it!

Basically, what you do comes down to the application and the customer's
experctations of it. My general opinion, based on my own limited
experience, has been stated.


Alwyn

Neil Butterworth

unread,
Apr 22, 2002, 7:23:17 PM4/22/02
to
"Alwyn" <al...@alwyn.demon.co.uk> wrote in message
news:alwyn-6492B6....@news-text.blueyonder.co.uk...

I'm currently working on a Fee Management system for asset managers, one
component of which is a server which co-ordinates valuation requests,
calculates fees etc. If this doesn't work correctly the Asset Managers
clients will have their fees calculated wrongly and will complain bitterly.
I'm not aware of any bugs in this server at present (i.e. my defect list is
empty). Of course, there may be corners of its envelope that I haven't
probed yet, but I think I can confidently exclude rogue pointers and invalid
indexes from this (in fact I never saw one of thse during its development).

Other software with zero bugs? well, most basic UNIX commands, and even some
of the more complex tools such as vi spring to mind.

NeilB


Alwyn

unread,
Apr 22, 2002, 7:36:21 PM4/22/02
to

Then you must be well above the general level of programmer I see.

> Other software with zero bugs? well, most basic UNIX commands, and even some
> of the more complex tools such as vi spring to mind.

I've no idea whether those have got bugs in (my uninformed guess would
be that they do), but most of the Unix tools have been through a great
number of revisions over time.

As far as I'm concerned, a bug-free complex piece of software is a
chimaera: you may strive for it, and for a while, it may even seem to be
within your grasp, but at the end of the day, it proves as elusive as
ever.


Alwyn

Jay O'Connor

unread,
Apr 22, 2002, 8:59:31 PM4/22/02
to

No it's not. You've added range checking, just external to the
collection.

Which is a good question, range checking on the index to access a
collection is sometimes neccessary, it's just a question of whether
the responsibility should belong to the collection or to the clients
of the collection

Take care,

Jay O'Connor
joco...@cybermesa.com
http://www.cybermesa.com/~joconnor


"God himself plays on the bass strings first, when he tunes the soul"

Bill Godfrey

unread,
Apr 23, 2002, 4:14:35 AM4/23/02
to
"Neil Butterworth" <neil_but...@lineone.net> writes:

> I can't see the point of range checks on a vector myself. You are either
> stepping through the thing with an iterator or using an index which you
> compare against the vector's size() member. In either case, how can you have
> an out of range error? And if you do get one, how are you going to recover
> from it?

If I get an out of range error, I (or a collegue) goofed. It's a bug.
Detect it and fix it as soon as humanly possible.

Yes, compare it against size, but why not have operator[] do it, so I
don't forget.

Maybe have vector<> and safe_vector<> instead? (And I'll just #define
vector safe_vector)

As for asserts, the usual behaviour is to stop the program. I prefer
a log file, but that's just me.

Bill, paranoid.

Bill Godfrey

unread,
Apr 23, 2002, 4:21:22 AM4/23/02
to
Alwyn <al...@alwyn.demon.co.uk> writes:

> But a failed 'assert' will terminate your program, won't it?

If you don't write your own (which is dubious in itself) yes.

An out of range error is a bug, which needs fixing. IMO, bring these
to prominence. (Sure, there are times when you don't want to do that.)

This seems an ideal application for the pre-processor, switching checks on
and off. You are still allowed to use it y'know!

Bill, C programmer.

Alexander Terekhov

unread,
Apr 23, 2002, 6:53:05 AM4/23/02
to

I agree. I'd even say that ANYTHING really *unexpected*[1],
is just "indication of one thing - your code has bugs in it"
that need to be recovered (with subsequent service-team
involvement using crash/core-dump-like things for the fix
in the next release/service level) on a somewhat HIGHER level
of recovery via restart-from-the-last-check-point/perhaps-retry/
get-rid-of-"bad"-input-and-continue.

> Hehehe, I'm sure you can't name me a substantial program that doesn't
> have bugs in it!

How about the infamous IEFBR14 -- one-liner/do-nothing
(this funny thing is sort-of-"moral" equivalent of
*void* main() {} ;-)).

After 30 years or so in service and a couple of APARs
(bug/fixes) per its ONE only line of code/instruction...
I guess, it is pretty "stable" now!

http://groups.google.com/groups?as_umsgid=3431BCC3.A4D4F3B6%40cpuperform.com
http://groups.google.com/groups?as_umsgid=1274%40orca.UUCP
http://groups.google.com/groups?as_umsgid=787167944.AA03215%40jina.rain.com

well, but I'd probably NOT bet a lot of cash that
it is fully bug-free even now! ;-)

> Basically, what you do comes down to the application and the customer's
> experctations of it. My general opinion, based on my own limited
> experience, has been stated.

How about the following concept (which was primarily
driven by the "customer's expectations", BTW):

http://www.ibm.com/servers/eserver/zseries/software/sa/pdf/ingpie02.pdf
(see "Recovery Concept for the Automation Manager"...
"StateQueue/Takeover file" is *C++ objects store*,
updated incrementally WITH transactional semantics.
It works even with system BLOWUPs/LOSSOFPOWER/...)

regards,
alexander.

[1]
http://groups.google.com/groups?as_umsgid=c29b5e33.0202161451.2ef75f1f%40posting.google.com
(see "#excep_defs" link; NO answer/reply yet, unfortunately ;-))

Richard Heathfield

unread,
Apr 23, 2002, 8:15:52 AM4/23/02
to
Alexander Terekhov wrote:
>
> Alwyn wrote:
> >
<snip>

>
> > Hehehe, I'm sure you can't name me a substantial program that doesn't
> > have bugs in it!
>
> How about the infamous IEFBR14 -- one-liner/do-nothing
> (this funny thing is sort-of-"moral" equivalent of
> *void* main() {} ;-)).

Your moral equivalent has a bug in it, as I'm sure you know. I believe
IEFBR14 had the /same/ bug. Possibly you knew that, too. :-)

>
> After 30 years or so in service and a couple of APARs
> (bug/fixes) per its ONE only line of code/instruction...
> I guess, it is pretty "stable" now!

Sure. But I wonder if it counts as a "substantial program". I'm not
denying it's heavily used, of course.

<snip>

--
Richard Heathfield : bin...@eton.powernet.co.uk
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton

Alexander Terekhov

unread,
Apr 23, 2002, 9:41:15 AM4/23/02
to

Richard Heathfield wrote:
[...]

> > How about the infamous IEFBR14 -- one-liner/do-nothing
> > (this funny thing is sort-of-"moral" equivalent of
> > *void* main() {} ;-)).
>
> Your moral equivalent has a bug in it, as I'm sure you know. I believe
> IEFBR14 had the /same/ bug. Possibly you knew that, too. :-)

;-)

BTW, AFAICT, the moral equivalent *FIX* (in C++) is just this:

int main() {}

because:

"If control reaches the end of main without encountering a
return statement, the effect is that of executing return 0;"

which is exactly what IEFBR14 is/was supposed to do (well, "mostly"
;-)).

regards,
alexander.

Steve Heller

unread,
Apr 23, 2002, 9:47:51 AM4/23/02
to
Bill Godfrey <billg-...@bacchae.f9.co.uk.invalid> wrote:

>"Neil Butterworth" <neil_but...@lineone.net> writes:
>
>> I can't see the point of range checks on a vector myself. You are either
>> stepping through the thing with an iterator or using an index which you
>> compare against the vector's size() member. In either case, how can you have
>> an out of range error? And if you do get one, how are you going to recover
>> from it?
>
>If I get an out of range error, I (or a collegue) goofed. It's a bug.
>Detect it and fix it as soon as humanly possible.
>
>Yes, compare it against size, but why not have operator[] do it, so I
>don't forget.
>
>Maybe have vector<> and safe_vector<> instead? (And I'll just #define
>vector safe_vector)

I think it's interesting to note that Bjarne uses a range-checked
"Vec" rather than "vector" in "The C++ Programming Language, 3rd.
Ed.", for teaching purposes. For that matter, ALL my programs use a
range-checked vector implementation all the time... for exactly that
reason.

--
Steve Heller, WA0CPP
http://www.steveheller.com
Author of "Learning to Program in C++", Who's Afraid of C++?", "Who's Afraid of More C++?",
"Optimizing C++", and other books
Free online versions of "Who's Afraid of C++?" and "Optimizing C++" are now available
at http://www.steveheller.com/whos and http://www.steveheller.com/opt

Neil Butterworth

unread,
Apr 23, 2002, 9:51:48 AM4/23/02
to
"Steve Heller" <st...@steveheller.com> wrote in message
news:mcpacusvah34jjtgt...@4ax.com...

> Bill Godfrey <billg-...@bacchae.f9.co.uk.invalid> wrote:
>
> >"Neil Butterworth" <neil_but...@lineone.net> writes:
> >
> >> I can't see the point of range checks on a vector myself. You are
either
> >> stepping through the thing with an iterator or using an index which you
> >> compare against the vector's size() member. In either case, how can you
have
> >> an out of range error? And if you do get one, how are you going to
recover
> >> from it?
> >
> >If I get an out of range error, I (or a collegue) goofed. It's a bug.
> >Detect it and fix it as soon as humanly possible.
> >
> >Yes, compare it against size, but why not have operator[] do it, so I
> >don't forget.
> >
> >Maybe have vector<> and safe_vector<> instead? (And I'll just #define
> >vector safe_vector)
>
> I think it's interesting to note that Bjarne uses a range-checked
> "Vec" rather than "vector" in "The C++ Programming Language, 3rd.
> Ed.", for teaching purposes. For that matter, ALL my programs use a
> range-checked vector implementation all the time... for exactly that
> reason.

What exactly are you teaching by doing this?

NeilB


Steve Heller

unread,
Apr 23, 2002, 10:10:56 AM4/23/02
to
"Neil Butterworth" <neil_but...@lineone.net> wrote:

I'm afraid I don't understand your question.

Neil Butterworth

unread,
Apr 23, 2002, 10:18:37 AM4/23/02
to
"Steve Heller" <st...@steveheller.com> wrote in message
news:uqqacuka9e6kv1r82...@4ax.com...

It seems pretty simple to me - you said you use your own range-checked
vector in preference to std::vector when teaching/writing for beginners. You
must have some reason for doing this - I wondered what you were teaching
your pupils/readers by using such a thing?

NeilB


Daniel T.

unread,
Apr 23, 2002, 10:23:09 AM4/23/02
to
In article <mcpacusvah34jjtgt...@4ax.com>,
Steve Heller <st...@steveheller.com> wrote:

>Bill Godfrey <billg-...@bacchae.f9.co.uk.invalid> wrote:
>
>>"Neil Butterworth" <neil_but...@lineone.net> writes:
>>
>>> I can't see the point of range checks on a vector myself. You are either
>>> stepping through the thing with an iterator or using an index which you
>>> compare against the vector's size() member. In either case, how can you
>>> have
>>> an out of range error? And if you do get one, how are you going to recover
>>> from it?
>>
>>If I get an out of range error, I (or a collegue) goofed. It's a bug.
>>Detect it and fix it as soon as humanly possible.
>>
>>Yes, compare it against size, but why not have operator[] do it, so I
>>don't forget.
>>
>>Maybe have vector<> and safe_vector<> instead? (And I'll just #define
>>vector safe_vector)
>
> I think it's interesting to note that Bjarne uses a range-checked
>"Vec" rather than "vector" in "The C++ Programming Language, 3rd.
>Ed.", for teaching purposes. For that matter, ALL my programs use a
>range-checked vector implementation all the time... for exactly that
>reason.

I just went in and changed the vector class. In debug mode, I wrote it
to defer to 'at'.

Steve Heller

unread,
Apr 23, 2002, 10:40:12 AM4/23/02
to
"Neil Butterworth" <neil_but...@lineone.net> wrote:

That a range-checked vector type is better than an array or a
non-range-checked vector type, I guess.
But I didn't do it to teach them that, but to give them something to
use that would be safer than arrays or "plain" vectors while having
the same syntax. That's the same reason that Bjarne does it.

Steve Heller

unread,
Apr 23, 2002, 10:41:38 AM4/23/02
to
"Daniel T." <notda...@gte.net> wrote:

I can't recommend that particular way of adding range-checking.
Changing the standard library headers is not a good idea.

Daniel T.

unread,
Apr 23, 2002, 11:07:44 AM4/23/02
to
Steve Heller <st...@steveheller.com> wrote:

>"Daniel T." <notda...@gte.net> wrote:
>
>>In article <mcpacusvah34jjtgt...@4ax.com>,
>> Steve Heller <st...@steveheller.com> wrote:
>>> I think it's interesting to note that Bjarne uses a range-checked
>>>"Vec" rather than "vector" in "The C++ Programming Language, 3rd.
>>>Ed.", for teaching purposes. For that matter, ALL my programs use a
>>>range-checked vector implementation all the time... for exactly that
>>>reason.
>>
>>I just went in and changed the vector class. In debug mode, I wrote it
>>to defer to 'at'.
>
> I can't recommend that particular way of adding range-checking.
>Changing the standard library headers is not a good idea.

Of course, I wouldn't tell a beginner to go in and do something like
that either. :-)

Edwin Robert Tisdale

unread,
Apr 23, 2002, 11:47:39 AM4/23/02
to
"Daniel T." wrote:

> I just went in and changed the vector class.
> In debug mode, I wrote it to defer to 'at'.

That sounds like a really BAD idea.
member function at() throws an exception -- out_of_range --
when passed a subscript that is out of range.
Application programs that use member operator[]()
don't expect it to throw an exception
so they don't include code to catch it.


Alexander Terekhov

unread,
Apr 23, 2002, 12:24:24 PM4/23/02
to

Neil Butterworth wrote:
[...]

> > >> I think it's interesting to note that Bjarne uses a range-checked
> > >> "Vec" rather than "vector" in "The C++ Programming Language, 3rd.
> > >> Ed.", for teaching purposes. For that matter, ALL my programs use a
> > >> range-checked vector implementation all the time... for exactly that
> > >> reason.
> > >
> > >What exactly are you teaching by doing this?
> >
> > I'm afraid I don't understand your question.
>
> It seems pretty simple to me - you said you use your own range-checked
> vector in preference to std::vector when teaching/writing for beginners. You
> must have some reason for doing this - I wondered what you were teaching
> your pupils/readers by using such a thing?

http://technetcast.ddj.com/tnc_play_stream.html?stream_id=560
("C++0x"/Stroustrup/"embarrassments&studens"/@10:39min)

But you, Neil (and other COPS too) should better relax a bit
from policing this NG and enjoy THE ENTIRE 87 MIN OF THAT MP3! ;-)

regards,
alexander.

P.S. If/when you see the folks from that "Panel"
please tell them:

A) "Offer a merger of C and C++ standards " -- BRAVO!

B) "support for multi-threaded programming" -- BRAVO!

C) "a single model of concurrency does not -- *SUCKS*
serve everyone well..." -- *SUCKS*
.....
*SUCKS*
-----
x1000

for low level medium- to fine-grained parallelism/concurrency
with *effective* resource sharing and synchronization:

GO ANSI-C WAY: POSIX THREADS (IN <cthread>; its
ALREADY the standard ANSI/IEEE/ISO/... extension
to ANSI/ISO-C) WITH ADDITIONAL C++ BINDINGS/WRAPPERS
(IN <thread>)!! http://sources.redhat.com/pthreads-win32

Alexander Terekhov

unread,
Apr 23, 2002, 12:31:19 PM4/23/02
to

Why should they?

Ever heard of UNEXPECTED exceptions (thrown from nothrow
"places", for example), which should NEVER be caught...
other than by terminate()/core-dumped handlers AT THROW
POINT (Ex.Specs and unexpected() aside, for a moment)?

regards,
alexander.

Daniel T.

unread,
Apr 23, 2002, 1:05:06 PM4/23/02
to

Which causes the exception to go all the way up to main where it is
caught and the programmer is notified before the program shuts down.
We've caught a lot of memory overrights this way over the past several
years.

Tom Plunket

unread,
Apr 23, 2002, 1:48:56 PM4/23/02
to
Neil Butterworth wrote:

> > Hehehe, I'm sure you can't name me a substantial program that doesn't
> > have bugs in it!
>

> I'm currently working on... but I think I can confidently exclude

> rogue pointers and invalid indexes from this (in fact I never saw
> one of thse during its development).
>
> Other software with zero bugs? well, most basic UNIX commands,
> and even some of the more complex tools such as vi spring to
> mind.

My management has criticized me for writing software that prints
error messages when it's used improperly. I think that they'd
rather see the bug report (on someone else's list) of a crash
than let the software keep running...

<sigh>

-tom!

Neil Butterworth

unread,
Apr 23, 2002, 2:07:13 PM4/23/02
to
"Tom Plunket" <to...@fancy.org> wrote in message
news:9h7bcuctkdiuc2sek...@4ax.com...

I once started as manager on a project where the then current team was doing
stuff like this:

// Precondition: s must never be NULL

void DoSomethingEssential( EssentialStructure * s ) {
if ( s != NULL ) {
s->ExecutePrimeBusinuessRule();
}
}

In other words, when a precondition failed they did nothing, which was
incorrect from a business perspective, but the code would never report this
or even core dump, just accumulate errors in the business logic. This was
infuriatingly hard to track down.

NeilB

Alexander Terekhov

unread,
Apr 23, 2002, 4:38:58 PM4/23/02
to

Core-/crash-dumps/JIT-debugging aside, I'm just curious:
have you ever used THREADS in your programs... with all
those scoped locking guards/auto-unlockers (anything else
that COULD result in "touching"/"messing with" the broken
state [all bets are off: NO exception safety guarantees
hold anymore] on the way up to your exciting catch-everything
hanlder(s) in main() aside too)?

regards,
alexander.

Daniel T.

unread,
Apr 23, 2002, 5:45:19 PM4/23/02
to
In article <3CC5C662...@web.de>,
Alexander Terekhov <tere...@web.de> wrote:

>"Daniel T." wrote:
>>
>> Edwin Robert Tisdale <E.Robert...@jpl.nasa.gov> wrote:
>>
>> >"Daniel T." wrote:
>> >
>> >> I just went in and changed the vector class.
>> >> In debug mode, I wrote it to defer to 'at'.
>> >
>> >That sounds like a really BAD idea.
>> >member function at() throws an exception -- out_of_range --
>> >when passed a subscript that is out of range.
>> >Application programs that use member operator[]()
>> >don't expect it to throw an exception
>> >so they don't include code to catch it.
>>
>> Which causes the exception to go all the way up to main where it is
>> caught and the programmer is notified before the program shuts down.
>> We've caught a lot of memory overrights this way over the past several
>> years.
>
>Core-/crash-dumps/JIT-debugging aside, I'm just curious:
>have you ever used THREADS in your programs...

No. Even so, the point is to be able to find out-of-range errors quickly
and putting a break point in the out_of_range c_tor is easy to do, if
you actually use 'at' or otherwise cause an out_of_range object to be
created when you go out of range...

>with all
>those scoped locking guards/auto-unlockers (anything else
>that COULD result in "touching"/"messing with" the broken
>state [all bets are off: NO exception safety guarantees
>hold anymore] on the way up to your exciting catch-everything
>hanlder(s) in main() aside too)?

No state is broken. The system throws the exception *before* the pointer
is dereferenced. The only thing I have to worry about is if someone does:

try {
myVec[5] = 3;
}
catch ( std::out_of_range& err ) { }

Which of course no one does. :-)

One programmer on the team got so sick of my system bailing out on a
out_of_range exception in his code that he started using 'at' all the
time instead of operator[] so he could catch the problems himself. Since
the compiler gives 0 runtime overhead if the exception is never thrown,
the program didn't suffer at all.

Alexander Terekhov

unread,
Apr 23, 2002, 6:49:39 PM4/23/02
to

"Daniel T." wrote:
[...]

> >Core-/crash-dumps/JIT-debugging aside, I'm just curious:
> >have you ever used THREADS in your programs...
>
> No. Even so, the point is to be able to find out-of-range errors quickly
> and putting a break point in the out_of_range c_tor is easy to do, if
> you actually use 'at' or otherwise cause an out_of_range object to be
> created when you go out of range...

Gee! You have customers who are running products under debuggers,
with brake points, etc!! Please *send me* the contact address(s)
as "Reply to Sender Only", PLEASE! (we can arrange something in
exchange; !!sure!!) ;-)

> >with all
> >those scoped locking guards/auto-unlockers (anything else
> >that COULD result in "touching"/"messing with" the broken
> >state [all bets are off: NO exception safety guarantees
> >hold anymore] on the way up to your exciting catch-everything
> >hanlder(s) in main() aside too)?
>
> No state is broken.

Well, again, think of it as *unexpected* SIGSEGV...

So, let me repeat/rephrase the question:

Why do you think (what makes you so sure) that
"No state is broken" given that someone just
had made a coding error/bug in this or that layer
that manifested itself with some UNEXPECTED (*damn*)
exception thrown, like: out_of_range, etc. Oh, e.g. (like):

pthread_exc_aritherr_e Unhandled floating-point exception signal
("arithmetic error")
pthread_exc_decovf_e Unhandled decimal overflow exception
pthread_exc_excpu_e "cpu-time limit exceeded"
pthread_exc_exfilsiz_e "File size limit exceeded"
pthread_exc_exquota_e Operation failed due to insufficient quota
pthread_exc_fltdiv_e Unhandled floating-point/decimal divide by zero
exception
pthread_exc_fltovf_e Unhandled floating-point overflow exception
pthread_exc_fltund_e Unhandled floating-point underflow exception
pthread_exc_illaddr_e Data or object could not be referenced
pthread_exc_illinstr_e Unhandled illegal instruction signal ("illegal
instruction")
pthread_exc_insfmem_e Insufficient virtual memory for requested
operation
pthread_exc_intdiv_e Unhandled integer divide by zero exception
pthread_exc_intovf_e Unhandled integer overflow exception
pthread_exc_nopriv_e Insufficient privilege for requested operation
pthread_exc_privinst_e Unhandled privileged instruction fault
exception
pthread_exc_resaddr_e Unhandled reserved addressing fault exception
pthread_exc_resoper_e Unhandled reserved operand fault exception
pthread_exc_SIGABRT_e Unhandled signal ABORT
pthread_exc_SIGBUS_e Unhandled bus error signal
pthread_exc_SIGEMT_e Unhandled EMT signal
pthread_exc_SIGFPE_e Unhandled floating-point exception signal
pthread_exc_SIGILL_e Unhandled illegal instruction signal
pthread_exc_SIGIOT_e Unhandled IOT signal
pthread_exc_SIGPIPE_e Unhandled broken pipe signal
pthread_exc_SIGSEGV_e Unhandled segmentation violation signal
pthread_exc_SIGSYS_e Unhandled bad system call signal
pthread_exc_SIGTRAP_e Unhandled trace or breakpoint trap signal
pthread_exc_subrng_e Unhandled subscript out of range exception
pthread_exc_uninitexc_e Uninitialized exception raised
pthread_stackovf_e Attempted stack overflow was detected

etc. etc. <whatever>

regards,
alexander.

Daniel T.

unread,
Apr 23, 2002, 11:19:35 PM4/23/02
to
In article <3CC5E503...@web.de>,
Alexander Terekhov <tere...@web.de> wrote:

>"Daniel T." wrote:
>[...]
>> >Core-/crash-dumps/JIT-debugging aside, I'm just curious:
>> >have you ever used THREADS in your programs...
>>
>> No. Even so, the point is to be able to find out-of-range errors quickly
>> and putting a break point in the out_of_range c_tor is easy to do, if
>> you actually use 'at' or otherwise cause an out_of_range object to be
>> created when you go out of range...
>
>Gee! You have customers who are running products under debuggers,
>with brake points, etc!! Please *send me* the contact address(s)
>as "Reply to Sender Only", PLEASE! (we can arrange something in
>exchange; !!sure!!) ;-)

No, I have customers who are running products that have debugging logs
and assertions and exceptions enabled. When they get notified of an
out_of_range exception, they give us the path, and we remove the defect.

Eventually, they decide that the product is "good enough" and we remove
the debugging information. They then sell the product to *their*
customers.

>> >with all
>> >those scoped locking guards/auto-unlockers (anything else
>> >that COULD result in "touching"/"messing with" the broken
>> >state [all bets are off: NO exception safety guarantees
>> >hold anymore] on the way up to your exciting catch-everything
>> >hanlder(s) in main() aside too)?
>>
>> No state is broken.
>
>Well, again, think of it as *unexpected* SIGSEGV...
>
>So, let me repeat/rephrase the question:
>
>Why do you think (what makes you so sure) that
>"No state is broken" given that someone just
>had made a coding error/bug in this or that layer
>that manifested itself with some UNEXPECTED (*damn*)
>exception thrown, like: out_of_range, etc. Oh, e.g. (like):

Again, we don't use threads. As I said before, this style has saved us
much time and heartache by finding out of bounds errors quickly and
painlessly. What is the point you are trying to make?

Alexander Terekhov

unread,
Apr 24, 2002, 8:02:27 AM4/24/02
to

"Daniel T." wrote:
[...]

> >Well, again, think of it as *unexpected* SIGSEGV...
> >
> >So, let me repeat/rephrase the question:
> >
> >Why do you think (what makes you so sure) that
> >"No state is broken" given that someone just
> >had made a coding error/bug in this or that layer
> >that manifested itself with some UNEXPECTED (*damn*)
> >exception thrown, like: out_of_range, etc. Oh, e.g. (like):
>
> Again, we don't use threads.

You DO USE "threads" -- you use "main" thread only, also
known as "initial" thread. The exception types I've posted
here essentially come from the *exception support* library;
NOT "threads library" (libexc*** IS thread-safe, however,
and threads library "wraps" some pure libexc stuff a little
bit).

> What is the point you are trying to make?

Forget it. Catch everything and be Happy!

regards,
alexander.

[***]

http://www.tru64unix.compaq.com/docs/base_doc/DOCUMENTATION/V51A_HTML/ARH9MBTE/VNTPRCSS.HTM#gentrap-expt-code-values-table

http://www.tru64unix.compaq.com/docs/base_doc/DOCUMENTATION/V51A_HTML/MAN/MAN3/0301____.HTM

http://groups.google.com/groups?as_umsgid=34B4BD85.5D585EF2%40zko.dec.com

Daniel T.

unread,
Apr 24, 2002, 8:37:21 AM4/24/02
to
Alexander Terekhov <tere...@web.de> wrote:

>"Daniel T." wrote:
>[...]
>> >Well, again, think of it as *unexpected* SIGSEGV...
>> >
>> >So, let me repeat/rephrase the question:
>> >
>> >Why do you think (what makes you so sure) that
>> >"No state is broken" given that someone just
>> >had made a coding error/bug in this or that layer
>> >that manifested itself with some UNEXPECTED (*damn*)
>> >exception thrown, like: out_of_range, etc. Oh, e.g. (like):
>>
>> Again, we don't use threads.
>
>You DO USE "threads" -- you use "main" thread only, also
>known as "initial" thread. The exception types I've posted
>here essentially come from the *exception support* library;

What "exception support" library may this be? I know not of what you
speak. I dare say it's not part of the standard is it?

>NOT "threads library" (libexc*** IS thread-safe, however,
>and threads library "wraps" some pure libexc stuff a little
>bit).

Again, what is libexc***? What "thread library" are you talking about. I
doub't I'm using it...

>> What is the point you are trying to make?
>
>Forget it. Catch everything and be Happy!

Catching bugs is what its all about sometimes.

0 new messages