What's the reason for disabling assert?

V

Victor Bazarov

DeMarcus said:
What are the reasons, except for speed, to disable asserts?

If you can answer "what are the reasons for disabling debug printouts?"
then you already know the answer to your question.

Assertions are debugging and testing tools. Once the program has been
debugged (and is presumed correct), they are nothing but hindrance for
using the program. If some code does nothing for the result of using
the program, why keep it there? It's not as simple, of course. Not all
diagnostic elements get removed from the final product. You can decide
that you need to keep asserts (or even give the user a debug version of
your program sometimes), all depends on what your goals are.

V
 
D

DeMarcus

Victor said:
If you can answer "what are the reasons for disabling debug printouts?"
then you already know the answer to your question.

Yes and no. Code-trace printouts may not be wanted when one stage is
finalized since they clutter the console or log. An assert on the other
hand is always welcome to me. Speed would be the only reason I can see
to disable them.

Therefore I have a follow up question. I don't like macros (let's take
the macro discussion later) so therefore I thought speed could be saved
by using lambdas like this.


newAssert( [&](){ realAssert( myPtr != nullptr ); } );

inline newAssert( std::function<void()> myLambda )
{
if( assertEnabled )
myLambda();
}

Now the speed difference is only one if-statement.

There are a few things I miss doing like this, like having the
expression itself in the assert printout, but if we focus on the speed
saving discussion, is this a smart way of postponing tasks that may be
disabled? I was thinking that this idea could be used with normal
printouts as well where we maybe want to construct a big amount of
detailed data from current scope.

/Daniel
 
A

Andrew Poelstra

Therefore I have a follow up question. I don't like macros (let's take
the macro discussion later) so therefore I thought speed could be saved
by using lambdas like this.


newAssert( [&](){ realAssert( myPtr != nullptr ); } );

inline newAssert( std::function<void()> myLambda )
{
if( assertEnabled )
myLambda();
}

Now the speed difference is only one if-statement.

No, with assertions enabled, you:
1. Call a function
2. The if-statement
3. Dereference another function and call that

With assertions disabled you can drop #3.

Whereas with assert() and assertions enabled, you have:
1. Whatever you passed to assert()

And with assertions disabled,
0. Nothing.

Not to mention the added code complexity and potential maintenance
confusion. Not to mention you can't disable it via NDEBUG like any
sane development environment would...
There are a few things I miss doing like this, like having the
expression itself in the assert printout,

....and not to mention that.
but if we focus on the speed
saving discussion, is this a smart way of postponing tasks that may be
disabled?

Absolutely not.
I was thinking that this idea could be used with normal
printouts as well where we maybe want to construct a big amount of
detailed data from current scope.

...by switching scopes and reducing the data to zero?
 
B

Brian Wood

It's not as simple, of course.  Not all
diagnostic elements get removed from the final product.  You can decide
that you need to keep asserts (or even give the user a debug version of
your program sometimes), all depends on what your goals are.

Making a debug version available to a user on line
and then working with the user to pinpoint the problem
is the way to go I think. Otherwise, the debug
version may fall into the wrong hands and be used to
reverse engineer your application.


Brian Wood
http://webEbenezer.net
(651) 251-9384
 
D

DeMarcus

Andrew said:
Therefore I have a follow up question. I don't like macros (let's take
the macro discussion later) so therefore I thought speed could be saved
by using lambdas like this.


newAssert( [&](){ realAssert( myPtr != nullptr ); } );

inline newAssert( std::function<void()> myLambda )
{
if( assertEnabled )
myLambda();
}
[...]
I was thinking that this idea could be used with normal
printouts as well where we maybe want to construct a big amount of
detailed data from current scope.

..by switching scopes and reducing the data to zero?

But aren't lambdas able to reach the current scope variables with [&]?
 
J

John H.

DeMarcus said:
What are the reasons, except for speed, to disable asserts?

[it] all depends on what your goals are.

I think Victor has it right here. asserts can be used in different
places depending on the developers aims.
Consider the example of displaying info about the program, which
includes showing the name of who the program is registered to. The
program is always suppose to be registered to someone. In parts of
the development and testing process, the developer wants to be made
aware of any inadvertent states where the program is not registered.
So they assert that the name should be valid. Now, the end-user
seeing an empty name in the "about" information might make them pause
for a second and wonder what is going on, but probably continue on
their way without too much distress. An aborting program might make
them pull their hair in frustration and be wary of using the software
at all. In this scenario the developer might prefer that in the
release build process, he wants NDEBUG defined near the code of the
about function. This could be done with a #define in the source or a
compiler flag. e.g.:

#include <iostream>
#ifndef _DEBUG
#ifndef NDEBUG
#define NDEBUG
#endif
#endif
#include <cassert>
void about(char const * registered_to)
{
if(registered_to == NULL)
registered_to = "";
assert(strlen(registered_to)>0 && "registered_to invalid name");
std::cout << "TheProgram (c) 1995\nRegistered to: " << registered_to
<< std::endl;
}
 
J

James Kanze

What are the reasons, except for speed, to disable asserts?

In most applications, not really. There are a few (e.g. games)
where stumbling on blindly, rather than aborting immediately,
are preferrable, but they're pretty much the exceptions; most of
the time, once you've detected that the program isn't behaving
as it should, the best thing to do is to exit as soon as
possible, executing as little additional code as possible.
 
J

James Kanze

If you can answer "what are the reasons for disabling debug
printouts?" then you already know the answer to your question.
Assertions are debugging and testing tools. Once the program
has been debugged (and is presumed correct),

If you can be 100% assured that your program has absolutely no
errors, then perhaps what you're saying would make sense. As it
is...
they are nothing but hindrance for using the program. If some
code does nothing for the result of using the program, why
keep it there?

Because it doesn't do nothing. It continues ensuring that your
code is behaving as designed.
 
I

Ian Collins

If you can be 100% assured that your program has absolutely no
errors, then perhaps what you're saying would make sense. As it
is...

Not just your program, but every other library and hardware device it
interacts with!
 
J

JustBoo

Making a debug version available to a user on line
and then working with the user to pinpoint the problem
is the way to go I think. Otherwise, the debug
version may fall into the wrong hands and be used to
reverse engineer your application.
Brian Wood

I've found meaningful output in log files to be very useful in
debugging software on remote machines. Most especially if the software
has no GUI. Sending them in email is usually easy.
 
T

tonydee

What are the reasons, except for speed, to disable asserts?

There are some valid reasons, but they're infrequently encountered.

James Kanze mentions games... a good example where flawed operation
may still provide an acceptable end-user experience, and - for some
issues such a rendering - there may be nothing more at risk than the
visual experience presented. Saving game state that doesn't meet
assertions is more of an issue if old state is thereby destroyed.

You could also have a situation where you're using an assert to check
for specific inputs you're aware of and have tested thoroughly -
wanting to know in a very attention-grabbing, un-ignorable way the
instant any other input arrives. Still, in production you may have
general-purpose handling that you expect is adequate, but just haven't
had the opportunity to test with this new input. An assertion in a
development build might model this situation well enough for your
purposes, but personally I'm loath to do anything that makes putting a
development build into production riskier.

And, while some people argue that continuing after an error invites
erroneous results that are worse than none at all, the way I view it
is that fast evolution of large software systems involves management
of a spectrum from rock-solid thoroughly-tested critical functionality
to little nice-to-have relatively unimportant features. For example,
document integrity after a cut/paste operation, versus a "non-
technical readability ratio" you're adding in for wow value and to try
to out-feature the competition despite no customers actually asking
for it. While an assertion failing in the former may (arguably)
justify stopping a production process, it can easily be better to
continue after a minor bug in the latter. If your style is to use
assertions in preference to logging to emphasise that the issue is a
development bug, then continuation requires disabling assertions in
the production build. Similarly, if you add some benchmarking code -
not part of the core functionality, but to guide further development -
you don't necessarily want to assert/abort because subtracting one
timestamp from another gave a negative or impossibly large result.
You might just log an warning and get on with life, but logging
doesn't give the same level of assurance of stamping out such issues
during the development process.

Cheers,
Tony
 
D

DeMarcus

tonydee said:
There are some valid reasons, but they're infrequently encountered.

James Kanze mentions games... a good example where flawed operation
may still provide an acceptable end-user experience, and - for some
issues such a rendering - there may be nothing more at risk than the
visual experience presented. Saving game state that doesn't meet
assertions is more of an issue if old state is thereby destroyed.

You could also have a situation where you're using an assert to check
for specific inputs you're aware of and have tested thoroughly -
wanting to know in a very attention-grabbing, un-ignorable way the
instant any other input arrives. Still, in production you may have
general-purpose handling that you expect is adequate, but just haven't
had the opportunity to test with this new input. An assertion in a
development build might model this situation well enough for your
purposes, but personally I'm loath to do anything that makes putting a
development build into production riskier.

And, while some people argue that continuing after an error invites
erroneous results that are worse than none at all, the way I view it
is that fast evolution of large software systems involves management
of a spectrum from rock-solid thoroughly-tested critical functionality
to little nice-to-have relatively unimportant features. For example,
document integrity after a cut/paste operation, versus a "non-
technical readability ratio" you're adding in for wow value and to try
to out-feature the competition despite no customers actually asking
for it. While an assertion failing in the former may (arguably)
justify stopping a production process, it can easily be better to
continue after a minor bug in the latter. If your style is to use
assertions in preference to logging to emphasise that the issue is a
development bug, then continuation requires disabling assertions in
the production build. Similarly, if you add some benchmarking code -
not part of the core functionality, but to guide further development -
you don't necessarily want to assert/abort because subtracting one
timestamp from another gave a negative or impossibly large result.
You might just log an warning and get on with life, but logging
doesn't give the same level of assurance of stamping out such issues
during the development process.

Cheers,
Tony

Good point! With your input my summary is that there are at least three
possible states of assert in a release build.

* Completely disabled.
* Disabled but with logging.
* Enabled (aborting) with logging.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,147
Messages
2,570,835
Members
47,383
Latest member
EzraGiffor

Latest Threads

Top