How does assert benefit your code really?

I

Ian Collins

pinkfog said:
assert just let you avoid the errors which are not expected to happen.
you use if statement or try_catch statement to mend the errors which
may happen by accident.
Hope what i say is right.
No try_catch in C!
 
M

Marc Boyer

Le 11-04-2006 said:
" a.out: p113.c:8: main: Assertion `0' failed.
Aborted "

and a switch option NDEBUG, what other benefits does assert() provide
in any scope of designing, debugging/coding and/or testing?

Do you prefer the if statement of the language to the assert MACRO of
the precompiler?

To me, there are 3 differents uses of assert:

1) debuging
When debuging/developping, assert ensures that the logic of
your code is respected.
double get(Vector v, size_t index){
assert( index < size(v) ):
...
}

2) unitary tests
If you do not have a efficient framework for
unitary tests, assert is usefull.

void test_Vector(){
Vector v;
init(&v);
assert( size(v) == 0 );
add(&v, 1.0 );
assert( get(v,0) == 1.0 );
...
}

3) run-time error
The question of run-time errors is huge. In fact, assert
is only a mecanism, and your code should have a politic.
(Notice that bad user input or ressource lack is not a
"run time error").

It depends on your code: in embeded systems, sometime,
the better is to log the error and to reset. Then, assert
can be redefinied as log + reset. In an aplication done
for a home user with GUI, assert is not very user-friendly
solution. In a banking system, if a very strange thing occurs,
is it better to shut-down the system or to let the strange
thing occurs and to log it ? There is no general solution.
It depend.

One benefit of assert is that it is a macro. So, you should
associates differents behaviors to assert depending on
your politic.

At least, assert is often better than no error checking.
Its better to know that the code crashed with message
'assertion failed in toto.c:134' than it crashed when
the user sometime clicks on 'Save' button.


Marc Boyer
 
M

Manuel Tobias Schiller

Nonsense, to put it mildly. The only asserts that should be left
in production code should be intended to catch hardware errors. It
should not be possible to trigger them in any other manner.

I agree that ordinary user errors (wrong parameters/incorrect usage
etc.) should be handled with a decent error message on stderr. However,
catching things that "can't" happen with assert might be a good idea; in
my case, a user had set up his spooling system so strangely that it fed
valid input to my driver, however a 100 by 100 pixel wide input for an
A4 page at 600 dpi is ridiculous (and points to wrong usage of the other
filters in the print data filtering chain), and these small dimensions
triggered an "unthought-of" bug in the code that enforced page margins.
Having my printer filter abort with an assert is in this case better
then silently ignoring the issue, because one might damage hardware
otherwise.

Regards.

Manuel
 
A

Al Balmer

Having my printer filter abort with an assert is in this case better
then silently ignoring the issue

Why are those the only two options?

Surely you could replace the assert with an orderly shutdown in a
manner less frightening (and more informative) for the user.
 
K

Keith Thompson

Al Balmer said:
Why are those the only two options?

Surely you could replace the assert with an orderly shutdown in a
manner less frightening (and more informative) for the user.

In a "this-can't-happen" situation, an orderly shutdown might not be
possible.

If the only sensible response to an error condition is to go back and
fix the bug in the program, an assert() is likely to be appropriate.
If the condition is something that could happen due to external
conditions, assert() is in appropriate.
 
A

Al Balmer

In a "this-can't-happen" situation, an orderly shutdown might not be
possible.

If the only sensible response to an error condition is to go back and
fix the bug in the program, an assert() is likely to be appropriate.
If the condition is something that could happen due to external
conditions, assert() is in appropriate.

In the given scenario, that was my point. The print filter has valid
(sic) but silly input. Nothing irreversible has happened yet. An
assert() is not appropriate.

I actually can't remember, in over 20 years of C programming, a
situation where assert() was appropriate in a production program,
although I've used the equivalent in assembler (if the hardware screws
up, halt the processor and let the failsafes handle it.)
 
S

Stephen Sprunk

Manuel Tobias Schiller said:
I agree that ordinary user errors (wrong parameters/incorrect usage
etc.) should be handled with a decent error message on stderr. However,
catching things that "can't" happen with assert might be a good idea; in
my case, a user had set up his spooling system so strangely that it fed
valid input to my driver, however a 100 by 100 pixel wide input for an
A4 page at 600 dpi is ridiculous (and points to wrong usage of the other
filters in the print data filtering chain), and these small dimensions
triggered an "unthought-of" bug in the code that enforced page margins.
Having my printer filter abort with an assert is in this case better
then silently ignoring the issue, because one might damage hardware
otherwise.

Ah, but if you had thought to include the assert(), you should have also
thought to include error-handling code as well. Nobody says you have to
silently ignore errors (particularly user-induced ones) in production
builds.

However, assert() is intended to protect programmers from their own
mistakes; in theory, those mistakes will all be caught during development or
testing. For catching user errors, another mechanism should be used, even
if it's just dumping a message to stderr and aborting.

S

--
Stephen Sprunk "Stupid people surround themselves with smart
CCIE #3723 people. Smart people surround themselves with
K5SSS smart people who disagree with them." --Aaron Sorkin

*** Free account sponsored by SecureIX.com ***
*** Encrypt your Internet usage with a free VPN account from http://www.SecureIX.com ***
 
S

Stephen Sprunk

Keith Thompson said:
In C90, assert()'s argument is required to be of type int, so this
isn't guaranteed to work (though any reasonable definition of assert()
is unlikely to care). In C99, the argument merely has to be a scalar,
so the call is legal.

I generally write C99 and, if people need my code to work on older
compilers, I let them submit patches that account for the differences.
Nevertheless, I prefer the more explicit:

assert(param != NULL);

both because I find it clearer in the source code, and because the
argument is stringized and used in the error message:

assertion "param != NULL" failed: file "tmp.c", line 6

Good point.
[...]
One might also redefine assert() to print a message to stderr in
production builds instead of having the test preprocessed out. That's
the best of both worlds.

I'm not sure you can legally do that. What you can do is define an
assert-like macro with a different name.

I'll leave the final decision to the C experts, but IIRC the assert macro is
only defined if one includes <assert.h>, so if you don't include that file
you're legal defining your own. Not surprisingly, people who do this tend
to include their own "assert.h" in place of <assert.h>. Probably reduces
portability, but worst case you can change the ""s to <>s for troublesome
ports.

Anyways, legal or not, it's the single most re-defined standard macro out
there, and people expect it to work even if it's frowned on by ISO.

S

--
Stephen Sprunk "Stupid people surround themselves with smart
CCIE #3723 people. Smart people surround themselves with
K5SSS smart people who disagree with them." --Aaron Sorkin

*** Free account sponsored by SecureIX.com ***
*** Encrypt your Internet usage with a free VPN account from http://www.SecureIX.com ***
 
M

Manuel Tobias Schiller

In the given scenario, that was my point. The print filter has valid
(sic) but silly input. Nothing irreversible has happened yet. An
assert() is not appropriate.

I actually can't remember, in over 20 years of C programming, a
situation where assert() was appropriate in a production program,
although I've used the equivalent in assembler (if the hardware screws
up, halt the processor and let the failsafes handle it.)
You're right there, once one has recognized that an error can happen,
one should catch it and handle it appropriately (even if such handling
consists only of writing something to stderr and aborting the process),
however, I'm talking about the time before you realise that a certain
error can happen. In my case, I happened to spot this bug in my code
because it resulted in a negative number of scanlines to process (skip a
few scanlines on a page which has very few anyway, and you'll have the
nicest underflow you can imagine), and I had left that assert in the code
which triggered at once. Well, I guess that writing drivers without
documentation for the underlying hardware (the GDI printer) might
sometimes be a little different from writing ordinary applications because
asserts in production code do not neccessarily hurt in this particular
situation (remember, strictly speaking, you are never sure that you're
doing the right thing in your software...).

Anyway, I learned a lot about assert.

Thanks everyone.

Manuel
 

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

No members online now.

Forum statistics

Threads
474,176
Messages
2,570,950
Members
47,503
Latest member
supremedee

Latest Threads

Top