Subject:
|
Re: Design by Contract (long post)
|
Newsgroups:
|
lugnet.robotics.rcx
|
Date:
|
Thu, 8 Jan 2004 10:58:55 GMT
|
Viewed:
|
3243 times
|
| |
| |
In lugnet.robotics.rcx, Ross Crawford wrote:
|
In lugnet.robotics.rcx, Iain McInnes wrote:
Hi Iain!
|
I have created an assert() macro which works under BrickOS. For those
unfamiliar with assert(), it is a standard C macro whose purpose is to help
find bugs. It is integral to the design by contract style of programming
pioneered by Bertrand Meyer.
|
Cool!
|
#ifdef NDEBUG
#define assert(x) ((void)0)
#else
#define assert(x) if (x) {} else { assert_fail(); }
#endif
|
I have a question about this: If NDEBUG is defined, shouldnt it still
execute x? That is, shouldnt the code in assert.h (or wherever) be:
#ifdef NDEBUG
#define assert(x) (x)
#else
#define assert(x) if (x) {} else { assert_fail(); }
#endif
ROSCO
|
<delurk>
The first definition of assert is the correct, standard definition. However
there is a slight boo boo in the original post in the line:
assert (myptr = malloc (sizeof (mystruct));
Which will delete the malloc when NDEBUG is defined. Its a classic mistake
that bites even experienced programmers now and then.
the easy way round it is to write:
myptr = malloc (sizeof (mystruct));
assert(myptr!=NULL);
thus, the malloc always takes place, but the assert only occurs in debug
builds.
The reason for deleting the contents of the assert is that asserts commonly
consist of a logical check (often slow) that you DONT want to execute in
release builds, e.g.
assert(numAllocs+numFree==countBlocks());
leaving a dangling
numAllocs+numFree==countBlocks();
in release builds would be pointless (especially if countBlocks is a slow
function).
Another common solution is define a verify macro, this works almost the same
as the assert, but as you suggested still executes the contents of the macro:
#ifdef NDEBUG
#define verify(x) (x)
#else
#define verify(x) if (x) {} else { assert_fail(); }
#endif
then you can write:
verify (myptr = malloc (sizeof (mystruct));
this will execute the malloc in all builds, but only assert in debug builds.
Cheers Tim
</delurk>
|
|
Message has 1 Reply:
Message is in Reply To:
| | Re: Design by Contract (long post)
|
| (...) Hi Iain! (...) Cool! (...) I have a question about this: If NDEBUG is defined, shouldn't it still execute x? That is, shouldn't the code in assert.h (or wherever) be: #ifdef NDEBUG #define assert(x) (x) #else #define assert(x) if (x) else (...) (21 years ago, 8-Jan-04, to lugnet.robotics.rcx, FTX)
|
7 Messages in This Thread:
- Entire Thread on One Page:
- Nested:
All | Brief | Compact | Dots
Linear:
All | Brief | Compact
This Message and its Replies on One Page:
- Nested:
All | Brief | Compact | Dots
Linear:
All | Brief | Compact
|
|
|
|