473,396 Members | 1,970 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

NDEBUG and assert macros.

Ok, so once I'm done debugging my code(split across multiple modules)
using the assert macro, I would want to switch off all the assert
macros ued in the program. Does this mean I have to include:

#define NDEBUG

in every .c where I used assert or defining it one file would turn off
all assert macros in every file ?
Aug 1 '08 #1
9 21430
On 1 Aug, 10:44, pereges <Brol...@gmail.comwrote:
Ok, so once I'm done debugging my code(split across multiple modules)
using the assert macro, I would want to switch off all the assert
macros ued in the program. Does this mean I have to include:

#define NDEBUG

in every .c where I used assert or defining it one file would turn off
all assert macros in every file ?
It's going to have to be in every compilation unit (c file +
includes).
Many compilers support a -D option which enables you to define a macro
on the compilers command line.

gcc -DNDEBUG fred.c -ofred

or you could it in a header file and include the header file
in every c file. Then at least next time you'd only need
to change one file.

Some pitfalls with turning off assert()s. Are you *certain*
that none of them are essential eg. input validation.
Are you sure none of them have side effects?

assert (fopen (s, siseof s, in) != NULL);

--
Nick Keighley

... it is absurd to make elaborate security checks on
debugging runs, when no trust is put in the results, and
then remove them in production runs, when an erroneous
result could be expensive or disastrous.
C. A. R. Hoare
Aug 1 '08 #2
pereges <Br*****@gmail.comwrote:
Ok, so once I'm done debugging my code(split across multiple modules)
using the assert macro, I would want to switch off all the assert
macros ued in the program. Does this mean I have to include:
#define NDEBUG
in every .c where I used assert or defining it one file would turn off
all assert macros in every file ?
Every .c file that uses assert() must see the define. You can achieve
that by putting the line in every file. On the other hand, in a pro-
ject with a lot of source files one tends to have a header file that
gets included everywhere. If you have such a header file than the
simplest thing would be to put the define in that file.

Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
Aug 1 '08 #3
On Aug 1, 2:44*pm, pereges <Brol...@gmail.comwrote:
Ok, so once I'm done debugging my code(split across multiple modules)
using the assert macro, I would want to switch off all the assert
macros ued in the program. Does this mean I have to include:

#define NDEBUG

in every .c where I used assert or defining it one file would turn off
all assert macros in every file ?
<off-topic>
If you compiler supports defining it on invocation, you can have that
on the command line itself(gcc supports doing that). The general
approach is to have a Makefile with targets defined for both the
cases(defined and not defined). Even if you are debugging a single
file, a simple Makefile won't hurt. That will save you the trouble of
typing the macro definition again on again while compiling it.
</off-topic>

The other approach, would be to have the macro defined in a header
file and include it in every file you use. Before defining NDEBUG,
make sure that your assert() is not having any side effects.

assert ((fp = fopen (FILE_NAME, "rb")) != NULL); /*this will break
you code

/* the proper way to do it
fp = fopen (FILE_NAME, "rb");
assert (fp != NULL);
>assert (fopen (s, siseof s, in) != NULL);
I assume Nick either meant fgets or passed incorrect arguments to
fopen.
Aug 1 '08 #4
In article
<26**********************************@v8g2000prm.g ooglegroups.com>, rahul
<ra*********@gmail.comwrote:
...
assert ((fp = fopen (FILE_NAME, "rb")) != NULL); /*this will break
you code */

/* the proper way to do it */
fp = fopen (FILE_NAME, "rb");
assert (fp != NULL);
BAD example, since failure to open a file is ALWAYS a possibility, no
matter how well-debugged a program is. Assert is NOT for input validation,
only validation of data from other parts of the program.
Aug 1 '08 #5
On 1 Aug, 10:44, pereges <Brol...@gmail.comwrote:
Ok, so once I'm done debugging my code(split across multiple modules)
using the assert macro, I would want to switch off all the assert
macros ued in the program. Does this mean I have to include:

#define NDEBUG

in every .c where I used assert or defining it one file would turn off
all assert macros in every file ?
Actually, you need to ensure that NDEBUG is defined at the
point assert.h is included. So, if you write:

#include <assert.h>
#define NDEBUG

then assertions will still be enabled. It is generally (IMO)
a bad idea to define NDEBUG in the source itself. Instead,
define NDEBUG when you invoke your compiler. For example,
any of the following work in many environments:

$ $CC -DNDEBUG ... # Here, $CC is the path to your compiler
$ make CPPFLAGS=-DNDEBUG
$ ./configure CPPFLAGS=-DNDEBUG && make

Aug 2 '08 #6
On 1 Aug, 10:57, Nick Keighley <nick_keighley_nos...@hotmail.com>
wrote:
>On 1 Aug, 10:44, pereges <Brol...@gmail.comwrote:
>Ok, so once I'm done debugging my code(split across multiple modules)
using the assert macro, I would want to switch off all the assert
macros ued in the program.
<snip>
Some pitfalls with turning off assert()s. Are you *certain*
that none of them are essential eg. input validation.
Are you sure none of them have side effects?
If a program is using assert to validate input,
then it is abusing/misusing assert. If an assertion
has a side effect, it is a bug, for example:
assert( x = 0 ); /* oops, should be x == 0 */

In other words, if you can't turn off assertions and
still pass the test suite, the solution is to fix
the bug--it is *not* to avoid turning off the assertions.
The point relevant to the OP is that you are NOT
done debugging until you've turned off the assertions
and verified that the code still works.
Aug 2 '08 #7
On 1 Aug, 12:31, rahul <rahulsin...@gmail.comwrote:

/* the proper way to do it
fp = fopen (FILE_NAME, "rb");
assert (fp != NULL);
No. Absolutely NOT. This is utterly broken, wrong, and
heinous. This is NOT what assert is for. At all. Arghh.
If you want, you might do:

fp = Fopen( ... );
assert( fp != NULL );

This would serve as documentation to the maintainer that
the Fopen call will never return a NULL pointer. Or you
can do things like:

for( i = 0; i < N; i++) {
...
}
assert( i == N);

This documents to the maintainer that the loop
is constructed such that it will always terminate with i
hitting the upper bound. The purpose of assert is to
validate that something you believe must be true is
in fact true. Often as pre-conditions in a function call:

void add( const int *a, const int *b, int *c, size_t N )
{
size_t i;
assert( a != NULL );
assert( b != NULL );
assert( c != NULL );

for( i = 0; i < N; i++ )
c[i] = a[i] + b[i];
}

This is far safer than simply adding a comment that states
that none of the arguments can be a null pointer, since it
aborts when the unwary programmer attempts to pass a null
pointer. It is NOT doing validation. If you want to write
a function that validates, you can't use assert. For example:

int add( int *a, int *b, int *c)
{
int status = 0;
int A,B;

A = ( a == NULL ) ? 0 : *a;
B = ( b == NULL ) ? 0 : *b;
if( c == NULL )
status = -1
else
*c = A + B;
return status;
}

Here, there are some questions. For example, perhaps you want
this function to never overflow. So perhaps you might want to
ensure that it is never called with *a or *b larger than INT_MAX/2.
In that case, look through your code; if you believe that
condition is true, then make it an assertion.

assert is NOT for data validation, or to check a function call.
It is used to validate your logic and the implementation. It
should be thought of as documentation. You are telling both
the compiler and the maintainer that you believe something
will be true. If it is not, the compiler will tell you that
you are wrong by causing a run-time abort. Anytime you look at
a piece of code and think something like, "okay, right here,
either i is positive or j is odd", then write it out:
assert( i 0 || j % 2 );
This is much better than a comment for two reasons ( at least ):
1) It removes the ambiguity about the word "positive" (does it
include zero or not?)
2) It is validated by the compiler.
Aug 2 '08 #8
On Aug 2, 12:54 pm, William Pursell <bill.purs...@gmail.comwrote:
On 1 Aug, 12:31, rahul <rahulsin...@gmail.comwrote:
/* the proper way to do it
fp = fopen (FILE_NAME, "rb");
assert (fp != NULL);

No. Absolutely NOT. This is utterly broken, wrong, and
heinous. This is NOT what assert is for. At all. Arghh.
It might not be what assert is for, but it's not broken or wrong. (if
you don't mind the missing */)

<snip>
Aug 2 '08 #9
William Pursell wrote:
On 1 Aug, 12:31, rahul <rahulsin...@gmail.comwrote:

>/* the proper way to do it
fp = fopen (FILE_NAME, "rb");
assert (fp != NULL);

No. Absolutely NOT. This is utterly broken, wrong, and
heinous. This is NOT what assert is for. At all. Arghh.
If you want, you might do:

fp = Fopen( ... );
assert( fp != NULL );

This would serve as documentation to the maintainer that
the Fopen call will never return a NULL pointer. Or you
can do things like:

for( i = 0; i < N; i++) {
...
}
assert( i == N);

This documents to the maintainer that the loop
is constructed such that it will always terminate with i
hitting the upper bound. The purpose of assert is to
validate that something you believe must be true is
in fact true. Often as pre-conditions in a function call:

void add( const int *a, const int *b, int *c, size_t N )
{
size_t i;
assert( a != NULL );
assert( b != NULL );
assert( c != NULL );

for( i = 0; i < N; i++ )
c[i] = a[i] + b[i];
}

This is far safer than simply adding a comment that states
that none of the arguments can be a null pointer, since it
aborts when the unwary programmer attempts to pass a null
pointer. It is NOT doing validation. If you want to write
a function that validates, you can't use assert. For example:

int add( int *a, int *b, int *c)
{
int status = 0;
int A,B;

A = ( a == NULL ) ? 0 : *a;
B = ( b == NULL ) ? 0 : *b;
if( c == NULL )
But is it any more correct call this add with null pointer values
for 'a', 'b', or 'c' than a similar call of the previous add? Why would
one want to write a zero to *c when the function is called with clearly
invalid arguments. I personally would return the error value for all
these cases, not just when c is NULL.

I can't really decide whether using assert on function parameters is
appropriate or not. An error code, as in this code, might be silently
misused by the caller, but OTOH, it somehow seems better to *inform*
the caller of an erroneous call (thus giving it a chance to retry,
though how much real life code is this comprehensive?), than terminate
the program single-handedly. But then would checking parameters with
assert be more justified for a function that has no defined error
return codes?

IMHO assert seems much more appropriate when used to verify the
correctness of program state at various points than when it's used for
things like function parameter checking, return value checking etc.
status = -1
else
*c = A + B;
return status;
}

Here, there are some questions. For example, perhaps you want
this function to never overflow. So perhaps you might want to
ensure that it is never called with *a or *b larger than INT_MAX/2.
In that case, look through your code; if you believe that
condition is true, then make it an assertion.
In the calling code? If so I agree.

<snip>

Aug 2 '08 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Dave | last post by:
In a nutshell, what is the behavior of the assert() macro ***as proscribed by the C89 Standard*** (which I don't have)? Of course, it doens't appear in the C++ Standard since it's inherited from...
6
by: Alexander Malkis | last post by:
Why do programmers like to use NDEBUG instead of DEBUG? -- Best regards, Alex. PS. To email me, remove "loeschedies" from the email address given.
13
by: Matthias Kaeppler | last post by:
Hi, why can I use assert from <cassert> without resolving the std:: namespace? E.g.: #include <cassert> int main() { assert(true); // shouldn't this be: std::assert(true) ?
11
by: BigMan | last post by:
When should one prefer assert-ing to throwing an exception?
3
by: Tony Johansson | last post by:
Hello Experts! I'm reading a book called programming with design pattern revealed by Tomasz Muldner and here I read something that I don' work. The text in the book says "To offer the...
21
by: Giuseppe | last post by:
is assert() for debug only or not? Is it possible that I have seen the use of assert() in the Borland c++ 32 compiler (so assert is not for debug only)?
27
by: Daniel Vallstrom | last post by:
I'm having problems with inconsistent floating point behavior resulting in e.g. assert( x > 0.0 && putchar('\n') && x == 0.0 ); holding. (Actually, my problem is the dual one where I get...
47
by: Rob Thorpe | last post by:
In general, is it considered bad practice to use asserts in production code? What about writing a macro that does the same as assert but continues to work regardless of the state of NDEBUG? I...
13
by: priyanka | last post by:
Hi there, Can anyone show me how the assert() function works ? I need to develop my own assert() function instead of using the one defined in the assert.h file. It would be great if anyone could...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.