Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Assertions in principle

Reply
Thread Tools

Assertions in principle

 
 
jeffc226@yahoo.com
Guest
Posts: n/a
 
      03-02-2007
This might be less of a design issue than a C++ language issue per se,
but I have a problem with assertions. I mean, they work, of course.
But there's something I'm uncomfortable with that's never been
explained to my satisfaction.

I recently read this explanation. "There is an effective litmus test
to differentiate the cases in which you need to use assert and when
you need to use genuine error checking: you use error checking for
things that could happen, even very improbably. You use assert only
for things that you truly believe cannot possibly happen under any
circumstances. An assertion that fails always signals a design or a
programmer error - not a user error."

OK I can buy that. But what keeps going unmentioned is that
assertions are debug-mode only. Well, it's mentioned, but usually in
the context of increased efficiency at runtime since they're compiled
out.

I understand the idea that even the things you take for granted as
being true might not be true. Software has bugs, and today almost
every decent sized application uses third party supplements and
interfaces. Interfaces change, code versions change, versions of code
get mismatched. New permutations of hardware and software mixes are
constantly occurring.

And where does all this manifest itself? At the developer's box?
Sometimes. But the majority of time in a modern large application
with many users, it's very likely for a bug to show itself in the
field. And that is exactly where the assertion does not exist. Even
most test departments use release code, not debug code. What exactly
is the point of checking for "impossible" error situations only at the
developer's desk? That just doesn't make sense to me. The code gets
executed far too much outside of that environment, in ways the
original developer might not even have imagined, for that to be good
enough.

I would go so far as to say the original developer's box is precisely
where assertions are NOT needed, because that's the only place where a
debugger is available. (I see how they can come in handy, and force
you to resist making assumptions.) But you really need assertions (or
something) in environments where the debugger isn't available.

 
Reply With Quote
 
 
 
 
Dennis Jones
Guest
Posts: n/a
 
      03-02-2007

<> wrote in message
news: oups.com...

<snip>

> I recently read this explanation. "There is an effective litmus test
> to differentiate the cases in which you need to use assert and when
> you need to use genuine error checking: you use error checking for
> things that could happen, even very improbably. You use assert only
> for things that you truly believe cannot possibly happen under any
> circumstances. An assertion that fails always signals a design or a
> programmer error - not a user error."
>
> OK I can buy that. But what keeps going unmentioned is that
> assertions are debug-mode only. Well, it's mentioned, but usually in
> the context of increased efficiency at runtime since they're compiled
> out.


<snip>

> I would go so far as to say the original developer's box is precisely
> where assertions are NOT needed, because that's the only place where a
> debugger is available. (I see how they can come in handy, and force
> you to resist making assumptions.) But you really need assertions (or
> something) in environments where the debugger isn't available.


I agree. I think asserts should be left in release code, and you can
accomplish this by writing your own assert macro (appropriately for your
platform):

#define Assert(p) ((p) ? (void)0 : _assert(#p, __FILE__, __LINE__))

Of course, there may be cases where the assert condition is a time-consuming
task that you would not want your users to suffer in the field. I'm not
sure I know how best to handle that case, but one way might be to enable
asserts with a runtime flag that can be enabled at the user's discretion.
This has the advantage that the assert code is available if you need it, but
has the disadvantage that it doesn't help when you have a
difficult-to-reproduce error condition. Fortunately, most conditions for
which assert is beneficial are in fact programmer errors, and can be
reproduced readily.

- Dennis


 
Reply With Quote
 
 
 
 
jclinton@cox.net
Guest
Posts: n/a
 
      03-02-2007
On Mar 2, 8:08 am, "jeffc...@yahoo.com" <jeffc...@yahoo.com> wrote:
> This might be less of a design issue than a C++ language issue per se,
> but I have a problem with assertions. I mean, they work, of course.
> But there's something I'm uncomfortable with that's never been
> explained to my satisfaction.
>
> I recently read this explanation. "There is an effective litmus test
> to differentiate the cases in which you need to use assert and when
> you need to use genuine error checking: you use error checking for
> things that could happen, even very improbably. You use assert only
> for things that you truly believe cannot possibly happen under any
> circumstances. An assertion that fails always signals a design or a
> programmer error - not a user error."
>
> OK I can buy that. But what keeps going unmentioned is that
> assertions are debug-mode only. Well, it's mentioned, but usually in
> the context of increased efficiency at runtime since they're compiled
> out.
>
> I understand the idea that even the things you take for granted as
> being true might not be true. Software has bugs, and today almost
> every decent sized application uses third party supplements and
> interfaces. Interfaces change, code versions change, versions of code
> get mismatched. New permutations of hardware and software mixes are
> constantly occurring.
>
> And where does all this manifest itself? At the developer's box?
> Sometimes. But the majority of time in a modern large application
> with many users, it's very likely for a bug to show itself in the
> field. And that is exactly where the assertion does not exist. Even
> most test departments use release code, not debug code. What exactly
> is the point of checking for "impossible" error situations only at the
> developer's desk? That just doesn't make sense to me. The code gets
> executed far too much outside of that environment, in ways the
> original developer might not even have imagined, for that to be good
> enough.
>
> I would go so far as to say the original developer's box is precisely
> where assertions are NOT needed, because that's the only place where a
> debugger is available. (I see how they can come in handy, and force
> you to resist making assumptions.) But you really need assertions (or
> something) in environments where the debugger isn't available.


It's definitely a balancing act rather than a black and white thing.
I normally have (at least) two kinds of assert macros defined (so I
define my own rather than just use the standard 'assert'). One of
these will be turned off for a release/optimized build and one kept
on. Typically you want to put asserts all over the place -- it's
common to have one at the start of every function checking arguments
and at the end of the function checking the 'post condition'. With
so many asserts the performance can suffer for code that gets called a
lot. So places with high risk like major interfaces to other people's
code I might use an assert which stays active all the time, other
places more internal to my own code I will disable the asserts for a
release build.

Sure I could still suffer problems after release in my more internal
code, but I generally see the risk verses cost acceptable for that
code if I can do good testing before release.

btw, I often have a third type of assert that calls special debug mode
functions that check the inegrity of data structures. These are very
expensive, but are great for catching some problems. I may keep these
disabled even during some debugging to keep performance up.


 
Reply With Quote
 
jeffc226@yahoo.com
Guest
Posts: n/a
 
      03-02-2007
On Mar 2, 12:19 pm, "Dennis Jones" <nos...@nospam.com> wrote:
> I agree. I think asserts should be left in release code, and you can
> accomplish this by writing your own assert macro (appropriately for your
> platform):


I like that idea.

>I'm not
> sure I know how best to handle that case, but one way might be to enable
> asserts with a runtime flag that can be enabled at the user's discretion.


I like that idea too.

>Fortunately, most conditions for
> which assert is beneficial are in fact programmer errors, and can be
> reproduced readily.


Actually I was specifically thinking of all the cases I've run into
that *can't* be reproduced back at the developer's desk, due to the
vast number of variables and permutations in some of today's scenarios
(I say "scenario" instead of simply "application" because it's
becoming increasingly valid these days to think in terms of the entire
system, of which the application is just one part.) But putting
custom macros in release code, to be turned on when more feedback is
needed for a problem in the field, sounds like a good solution.

 
Reply With Quote
 
Andrew Koenig
Guest
Posts: n/a
 
      03-02-2007
<> wrote in message
news: oups.com...

> OK I can buy that. But what keeps going unmentioned is that
> assertions are debug-mode only.


What do you mean by this statement? The C++ standard has no notion of
"debug mode."

It is true that by setting a preprocessor variable named NDEBUG, you make
assertions go away. But it's up to you whether to do that. If you don't
think it's a good idea, don't do it.


 
Reply With Quote
 
Kaz Kylheku
Guest
Posts: n/a
 
      03-03-2007
On Mar 2, 8:08 am, "jeffc...@yahoo.com" <jeffc...@yahoo.com> wrote:
> This might be less of a design issue than a C++ language issue per se,
> but I have a problem with assertions. I mean, they work, of course.
> But there's something I'm uncomfortable with that's never been
> explained to my satisfaction.
>
> I recently read this explanation. "There is an effective litmus test
> to differentiate the cases in which you need to use assert and when
> you need to use genuine error checking: you use error checking for
> things that could happen, even very improbably. You use assert only
> for things that you truly believe cannot possibly happen under any
> circumstances. An assertion that fails always signals a design or a
> programmer error - not a user error."
>
> OK I can buy that. But what keeps going unmentioned is that
> assertions are debug-mode only.


The ANSI/ISO C assert, inherited into C++, is disabled by the presence
of the NDEBUG macro. This is not the same thing as being ``debug-mode
only''.

Debug mode is whatever your compiler, build environment and local
conventions dictate debug mode is.

Where I work, both debug and optimized builds have assertions enabled.

C. A. R. Hoare (of quicksort fame) wrote this sometime in the early
1970's:

It is absurd to make elaborate security checks on debugging runs,
when no trust is putin the results, and then remove them in
production runs, when an erroneous result could be expensive
or disastrous. What would we think of a sailing enthusiast who
wears his life-jacket when training on dry land but takes it
off as soon as he goes to sea?

So your argument finds good company, indeed.

> I would go so far as to say the original developer's box is precisely
> where assertions are NOT needed, because that's the only place where a
> debugger is available. (I see how they can come in handy, and force
> you to resist making assumptions.) But you really need assertions (or
> something) in environments where the debugger isn't available.


You need both. Under debugger, an assertion triggers the type of event
that causes the program to stop so that it can be debugged. Without
the assertion, the program will keep executing; it won't stop until
some fault occurs. By that time, in spite of the debugger being
available at that point, it may be harder to locate the root cause.
Assertions go off closer to the root causes of defects.


 
Reply With Quote
 
Alan Johnson
Guest
Posts: n/a
 
      03-03-2007
Kaz Kylheku wrote:
> C. A. R. Hoare (of quicksort fame) wrote this sometime in the early
> 1970's:
>
> It is absurd to make elaborate security checks on debugging runs,
> when no trust is putin the results, and then remove them in
> production runs, when an erroneous result could be expensive
> or disastrous. What would we think of a sailing enthusiast who
> wears his life-jacket when training on dry land but takes it
> off as soon as he goes to sea?
>
> So your argument finds good company, indeed.


I'm not sure I like Hoare's analogy. Consider this one: When you are
learning to ride a bicycle you attach training wheels to catch you when
you make a mistake. When you are competing in the Tour de France you no
longer use the training wheels. Analogously, when you are writing code
you use asserts to catch when your invariants stop being invariant.
After you are satisfied the code is correct you disable them for
performance.

That said, I do find the rest of the arguments compelling.

--
Alan Johnson
 
Reply With Quote
 
Chris Theis
Guest
Posts: n/a
 
      03-03-2007

"Alan Johnson" <> wrote in message
news:. ..
> Kaz Kylheku wrote:
>> C. A. R. Hoare (of quicksort fame) wrote this sometime in the early
>> 1970's:
>>
>> It is absurd to make elaborate security checks on debugging runs,
>> when no trust is putin the results, and then remove them in
>> production runs, when an erroneous result could be expensive
>> or disastrous. What would we think of a sailing enthusiast who
>> wears his life-jacket when training on dry land but takes it
>> off as soon as he goes to sea?
>>
>> So your argument finds good company, indeed.

>
> I'm not sure I like Hoare's analogy. Consider this one: When you are
> learning to ride a bicycle you attach training wheels to catch you when
> you make a mistake. When you are competing in the Tour de France you no
> longer use the training wheels. Analogously, when you are writing code
> you use asserts to catch when your invariants stop being invariant. After
> you are satisfied the code is correct you disable them for performance.

[SNIP]

But how do you actually "assert" that the code is correct? Running your own
tests, extended beta-testing etc. etc. is certainly a mandatory thing, but
it does not at all guarantee correct code in the sense, that it will act
correctly under each and every aspect that might come along.

IMO the sailing analogy hits the point. Staying with the analogies - even
those competing in the TDF wear helmets for safety, but not all of them. Of
course one would disable asserts in time critical parts in the production
code, but this is not necessarily useful throughout the whole program.
Especially when implementing complex parser/compiler systems they come in
extremely handy in code that is already shipped to customers.

Cheers
Chris


 
Reply With Quote
 
Roland Pibinger
Guest
Posts: n/a
 
      03-03-2007
On 2 Mar 2007 08:08:55 -0800, "jeffc226@...com" wrote:
>This might be less of a design issue than a C++ language issue per se,
>but I have a problem with assertions. I mean, they work, of course.
>But there's something I'm uncomfortable with that's never been
>explained to my satisfaction.
>
>I recently read this explanation. "There is an effective litmus test
>to differentiate the cases in which you need to use assert and when
>you need to use genuine error checking: you use error checking for
>things that could happen, even very improbably. You use assert only
>for things that you truly believe cannot possibly happen under any
>circumstances. An assertion that fails always signals a design or a
>programmer error - not a user error."


This is a very good explanation (source?). assert is for finding bugs
in a program. Input validation, error handling, ... is not done with
asserts. Therefore asserts should never be used in production
(release) code.

>OK I can buy that. But what keeps going unmentioned is that
>assertions are debug-mode only. Well, it's mentioned, but usually in
>the context of increased efficiency at runtime since they're compiled
>out.


Yes, that's their purpose. Actually, assert should be renamed to
debug_assert.

>I understand the idea that even the things you take for granted as
>being true might not be true. Software has bugs, and today almost
>every decent sized application uses third party supplements and
>interfaces. Interfaces change, code versions change, versions of code
>get mismatched. New permutations of hardware and software mixes are
>constantly occurring.


Well tested software has so few bugs that is can be smoothly used by
the client. And what have interface changes and mismatched code to do
with asserts?

>And where does all this manifest itself? At the developer's box?
>Sometimes. But the majority of time in a modern large application
>with many users, it's very likely for a bug to show itself in the
>field. And that is exactly where the assertion does not exist.


The bug crashes the program, assert calls abort which crashes the
program. So?

>Even most test departments use release code, not debug code.


Of course, they test the program that is shipped, not a debug version.

>What exactly
>is the point of checking for "impossible" error situations only at the
>developer's desk?


To find bugs in the program. Nothing more, nothing less. Together with
unit tests, functional tests, integration tests, ... it is one step to
produce a deployable program. Actually, assert can be seen as
automated test built into code.

>That just doesn't make sense to me. The code gets
>executed far too much outside of that environment, in ways the
>original developer might not even have imagined, for that to be good
>enough.


That just doesn't make sense to me. You write code that consists of
(public) interfaces to encapsulated code. You validate the input.
Since software is (should be) reusable it's no problem (even desired)
that it is used in ways 'the original developer might not even have
imagined'. You check the input as part of the contract between your
code and the caller. When the input is within the allowd range your
code must work.

>I would go so far as to say the original developer's box is precisely
>where assertions are NOT needed, because that's the only place where a
>debugger is available. (I see how they can come in handy, and force
>you to resist making assumptions.) But you really need assertions (or
>something) in environments where the debugger isn't available.


Using a debugger is the most inefficient activity in programming. It
is entirely resistant to automation. asserts help you avoid using the
debugger.
BTW, have you ever seen a program/library that prints/displays asserts
in production/release mode? I would be very reluctant to use that
program because the code quality most probably is very poor.

Best wishes,
Roland Pibinger
 
Reply With Quote
 
Chris Theis
Guest
Posts: n/a
 
      03-03-2007

"Roland Pibinger" <> wrote in message
news:...
[SNIP]
>
> This is a very good explanation (source?). assert is for finding bugs
> in a program. Input validation, error handling, ... is not done with
> asserts. Therefore asserts should never be used in production
> (release) code.


I absolutely agree on the point that input validation & user error handling
is not done with asserts. But in contrast to what you've stated I do not
quite see the causality why this would exclude using them in production
code? I'd very much appreciate if you could probably elaborate on this.

[SNIP]
> Using a debugger is the most inefficient activity in programming.


Sorry, I might seem to be thick but this is a statement which I do not
understand at all. What exactly do you mean by inefficient? In my
understanding the term inefficient relates to wasting time and considering
the use of a debugger as a waste of time sounds rather awsome to me. But
there might be a misunderstanding here.

> It is entirely resistant to automation. asserts help you avoid using the
> debugger


Let me summarize, you use the assert to avoid using the debugger and not
using the debugger helps you to be more efficient in programming. I actually
wonder how you check the state/value of variables, objects etc. in your
code.

> BTW, have you ever seen a program/library that prints/displays asserts
> in production/release mode? I would be very reluctant to use that
> program because the code quality most probably is very poor.


It actually makes sense to have production/release code printing asserts, or
rather dumping them in a file. Especially for large scale systems with lots
of modules, dynamic libs etc. it can come in very handy if the user has the
possibility to enable this assertion/logging mechanism while trying to
reproduce faulty behavior. It saves the developer a lot of time if such a
warning/error protocol is sent to him while trying to fix things being
remote from the customer.

Best regards
Chris

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Principle Engineer needed Joe Feldman C++ 14 05-06-2010 12:47 AM
interface principle bluekite2000@gmail.com C++ 3 08-12-2005 06:34 PM
Webmessenger principle CW ASP .Net 5 09-23-2004 02:14 AM
Dependency Inversion Principle Dilemma Thomas Matthews C++ 12 12-23-2003 08:51 PM
principle of stport std::sort Pavel Pluhacek C++ 2 09-01-2003 05:37 PM



Advertisments