140266059SGregory Neil Shapiro<html> 240266059SGregory Neil Shapiro<head> 340266059SGregory Neil Shapiro <title> libsm : Assert and Abort </title> 440266059SGregory Neil Shapiro</head> 540266059SGregory Neil Shapiro<body> 640266059SGregory Neil Shapiro 740266059SGregory Neil Shapiro<a href="index.html">Back to libsm overview</a> 840266059SGregory Neil Shapiro 940266059SGregory Neil Shapiro<center> 1040266059SGregory Neil Shapiro <h1> libsm : Assert and Abort </h1> 11*4313cc83SGregory Neil Shapiro <br> $Id: assert.html,v 1.6 2001-08-27 21:47:03 ca Exp $ 1240266059SGregory Neil Shapiro</center> 1340266059SGregory Neil Shapiro 1440266059SGregory Neil Shapiro<h2> Introduction </h2> 1540266059SGregory Neil Shapiro 1640266059SGregory Neil ShapiroThis package contains abstractions 1740266059SGregory Neil Shapirofor assertion checking and abnormal program termination. 1840266059SGregory Neil Shapiro 1940266059SGregory Neil Shapiro<h2> Synopsis </h2> 2040266059SGregory Neil Shapiro 2140266059SGregory Neil Shapiro<pre> 2240266059SGregory Neil Shapiro#include <sm/assert.h> 2340266059SGregory Neil Shapiro 2440266059SGregory Neil Shapiro/* 2540266059SGregory Neil Shapiro** abnormal program termination 2640266059SGregory Neil Shapiro*/ 2740266059SGregory Neil Shapiro 2840266059SGregory Neil Shapirovoid sm_abort_at(char *filename, int lineno, char *msg); 2940266059SGregory Neil Shapirotypedef void (*SM_ABORT_HANDLER)(char *filename, int lineno, char *msg); 3040266059SGregory Neil Shapirovoid sm_abort_sethandler(SM_ABORT_HANDLER); 3140266059SGregory Neil Shapirovoid sm_abort(char *fmt, ...) 3240266059SGregory Neil Shapiro 3340266059SGregory Neil Shapiro/* 3440266059SGregory Neil Shapiro** assertion checking 3540266059SGregory Neil Shapiro*/ 3640266059SGregory Neil Shapiro 3740266059SGregory Neil ShapiroSM_REQUIRE(expression) 3840266059SGregory Neil ShapiroSM_ASSERT(expression) 3940266059SGregory Neil ShapiroSM_ENSURE(expression) 4040266059SGregory Neil Shapiro 4140266059SGregory Neil Shapiroextern SM_DEBUG_T SmExpensiveRequire; 4240266059SGregory Neil Shapiroextern SM_DEBUG_T SmExpensiveAssert; 4340266059SGregory Neil Shapiroextern SM_DEBUG_T SmExpensiveEnsure; 4440266059SGregory Neil Shapiro 4540266059SGregory Neil Shapiro#if SM_CHECK_REQUIRE 4640266059SGregory Neil Shapiro#if SM_CHECK_ASSERT 4740266059SGregory Neil Shapiro#if SM_CHECK_ENSURE 4840266059SGregory Neil Shapiro 4940266059SGregory Neil Shapirocc -DSM_CHECK_ALL=0 -DSM_CHECK_REQUIRE=1 ... 5040266059SGregory Neil Shapiro</pre> 5140266059SGregory Neil Shapiro 5240266059SGregory Neil Shapiro<h2> Abnormal Program Termination </h2> 5340266059SGregory Neil Shapiro 5440266059SGregory Neil ShapiroThe functions sm_abort and sm_abort_at are used to report a logic 5540266059SGregory Neil Shapirobug and terminate the program. They can be invoked directly, 5640266059SGregory Neil Shapiroand they are also used by the assertion checking macros. 5740266059SGregory Neil Shapiro 5840266059SGregory Neil Shapiro<dl> 5940266059SGregory Neil Shapiro<dt> 6040266059SGregory Neil Shapiro void sm_abort_at(char *filename, int lineno, char *msg) 6140266059SGregory Neil Shapiro<dd> 6240266059SGregory Neil Shapiro This is the low level interface for causing abnormal program 6340266059SGregory Neil Shapiro termination. It is intended to be invoked from a 6440266059SGregory Neil Shapiro macro, such as the assertion checking macros. 6540266059SGregory Neil Shapiro 6640266059SGregory Neil Shapiro If filename != NULL then filename and lineno specify the line 6740266059SGregory Neil Shapiro of source code on which the logic bug is detected. These 6840266059SGregory Neil Shapiro arguments are normally either set to __FILE__ and __LINE__ 6940266059SGregory Neil Shapiro from an assertion checking macro, or they are set to NULL and 0. 7040266059SGregory Neil Shapiro 7140266059SGregory Neil Shapiro The default action is to print an error message to smioerr 7240266059SGregory Neil Shapiro using the arguments, and then call abort(). This default 7340266059SGregory Neil Shapiro behaviour can be changed by calling sm_abort_sethandler. 7440266059SGregory Neil Shapiro<p> 7540266059SGregory Neil Shapiro<dt> 7640266059SGregory Neil Shapiro void sm_abort_sethandler(SM_ABORT_HANDLER handler) 7740266059SGregory Neil Shapiro<dd> 7840266059SGregory Neil Shapiro Install 'handler' as the callback function that is invoked 7940266059SGregory Neil Shapiro by sm_abort_at. This callback function is passed the same 8040266059SGregory Neil Shapiro arguments as sm_abort_at, and is expected to log an error 8140266059SGregory Neil Shapiro message and terminate the program. The callback function should 8240266059SGregory Neil Shapiro not raise an exception or perform cleanup: see Rationale. 8340266059SGregory Neil Shapiro 8440266059SGregory Neil Shapiro sm_abort_sethandler is intended to be called once, from main(), 8540266059SGregory Neil Shapiro before any additional threads are created: see Rationale. 8640266059SGregory Neil Shapiro You should not use sm_abort_sethandler to 8740266059SGregory Neil Shapiro switch back and forth between several handlers; 8840266059SGregory Neil Shapiro this is particularly dangerous when there are 8940266059SGregory Neil Shapiro multiple threads, or when you are in a library routine. 9040266059SGregory Neil Shapiro<p> 9140266059SGregory Neil Shapiro<dt> 9240266059SGregory Neil Shapiro void sm_abort(char *fmt, ...) 9340266059SGregory Neil Shapiro<dd> 9440266059SGregory Neil Shapiro This is the high level interface for causing abnormal program 9540266059SGregory Neil Shapiro termination. It takes printf arguments. There is no need to 9640266059SGregory Neil Shapiro include a trailing newline in the format string; a trailing newline 9740266059SGregory Neil Shapiro will be printed if appropriate by the handler function. 9840266059SGregory Neil Shapiro</dl> 9940266059SGregory Neil Shapiro 10040266059SGregory Neil Shapiro<h2> Assertions </h2> 10140266059SGregory Neil Shapiro 10240266059SGregory Neil Shapiro The assertion handling package 10340266059SGregory Neil Shapiro supports a style of programming in which assertions are used 10440266059SGregory Neil Shapiro liberally throughout the code, both as a form of documentation, 10540266059SGregory Neil Shapiro and as a way of detecting bugs in the code by performing runtime checks. 10640266059SGregory Neil Shapiro<p> 10740266059SGregory Neil Shapiro There are three kinds of assertion: 10840266059SGregory Neil Shapiro<dl> 10940266059SGregory Neil Shapiro<dt> 11040266059SGregory Neil Shapiro SM_REQUIRE(expr) 11140266059SGregory Neil Shapiro<dd> 11240266059SGregory Neil Shapiro This is an assertion used at the beginning of a function 11340266059SGregory Neil Shapiro to check that the preconditions for calling the function 11440266059SGregory Neil Shapiro have been satisfied by the caller. 11540266059SGregory Neil Shapiro<p> 11640266059SGregory Neil Shapiro<dt> 11740266059SGregory Neil Shapiro SM_ENSURE(expr) 11840266059SGregory Neil Shapiro<dd> 11940266059SGregory Neil Shapiro This is an assertion used just before returning from a function 12040266059SGregory Neil Shapiro to check that the function has satisfied all of the postconditions 12140266059SGregory Neil Shapiro that it is required to satisfy by its contract with the caller. 12240266059SGregory Neil Shapiro<p> 12340266059SGregory Neil Shapiro<dt> 12440266059SGregory Neil Shapiro SM_ASSERT(expr) 12540266059SGregory Neil Shapiro<dd> 12640266059SGregory Neil Shapiro This is an assertion that is used in the middle of a function, 12740266059SGregory Neil Shapiro to check loop invariants, and for any other kind of check that is 12840266059SGregory Neil Shapiro not a "require" or "ensure" check. 12940266059SGregory Neil Shapiro</dl> 13040266059SGregory Neil Shapiro If any of the above assertion macros fail, then sm_abort_at 13140266059SGregory Neil Shapiro is called. By default, a message is printed to stderr and the 13240266059SGregory Neil Shapiro program is aborted. For example, if SM_REQUIRE(arg > 0) fails 13340266059SGregory Neil Shapiro because arg <= 0, then the message 13440266059SGregory Neil Shapiro<blockquote><pre> 13540266059SGregory Neil Shapirofoo.c:47: SM_REQUIRE(arg > 0) failed 13640266059SGregory Neil Shapiro</pre></blockquote> 13740266059SGregory Neil Shapiro is printed to stderr, and abort() is called. 13840266059SGregory Neil Shapiro You can change this default behaviour using sm_abort_sethandler. 13940266059SGregory Neil Shapiro 14040266059SGregory Neil Shapiro<h2> How To Disable Assertion Checking At Compile Time </h2> 14140266059SGregory Neil Shapiro 14240266059SGregory Neil Shapiro You can use compile time macros to selectively enable or disable 14340266059SGregory Neil Shapiro each of the three kinds of assertions, for performance reasons. 14440266059SGregory Neil Shapiro For example, you might want to enable SM_REQUIRE checking 14540266059SGregory Neil Shapiro (because it finds the most bugs), but disable the other two types. 14640266059SGregory Neil Shapiro<p> 14740266059SGregory Neil Shapiro By default, all three types of assertion are enabled. 14840266059SGregory Neil Shapiro You can selectively disable individual assertion types 14940266059SGregory Neil Shapiro by setting one or more of the following cpp macros to 0 15040266059SGregory Neil Shapiro before <sm/assert.h> is included for the first time: 15140266059SGregory Neil Shapiro<blockquote> 15240266059SGregory Neil Shapiro SM_CHECK_REQUIRE<br> 15340266059SGregory Neil Shapiro SM_CHECK_ENSURE<br> 15440266059SGregory Neil Shapiro SM_CHECK_ASSERT<br> 15540266059SGregory Neil Shapiro</blockquote> 15640266059SGregory Neil Shapiro Or, you can define SM_CHECK_ALL as 0 to disable all assertion 15740266059SGregory Neil Shapiro types, then selectively define one or more of SM_CHECK_REQUIRE, 15840266059SGregory Neil Shapiro SM_CHECK_ENSURE or SM_CHECK_ASSERT as 1. For example, 15940266059SGregory Neil Shapiro to disable all assertions except for SM_REQUIRE, you can use 16040266059SGregory Neil Shapiro these C compiler flags: 16140266059SGregory Neil Shapiro<blockquote> 16240266059SGregory Neil Shapiro -DSM_CHECK_ALL=0 -DSM_CHECK_REQUIRE=1 16340266059SGregory Neil Shapiro</blockquote> 16440266059SGregory Neil Shapiro 16540266059SGregory Neil Shapiro After <sm/assert.h> is included, the macros 16640266059SGregory Neil Shapiro SM_CHECK_REQUIRE, SM_CHECK_ENSURE and SM_CHECK_ASSERT 16740266059SGregory Neil Shapiro are each set to either 0 or 1. 16840266059SGregory Neil Shapiro 16940266059SGregory Neil Shapiro<h2> How To Write Complex or Expensive Assertions </h2> 17040266059SGregory Neil Shapiro 17140266059SGregory Neil Shapiro Sometimes an assertion check requires more code than a simple 17240266059SGregory Neil Shapiro boolean expression. 17340266059SGregory Neil Shapiro For example, it might require an entire statement block 17440266059SGregory Neil Shapiro with its own local variables. 17540266059SGregory Neil Shapiro You can code such assertion checks by making them conditional on 17640266059SGregory Neil Shapiro SM_CHECK_REQUIRE, SM_CHECK_ENSURE or SM_CHECK_ASSERT, 17740266059SGregory Neil Shapiro and using sm_abort to signal failure. 17840266059SGregory Neil Shapiro<p> 17940266059SGregory Neil Shapiro Sometimes an assertion check is significantly more expensive 18040266059SGregory Neil Shapiro than one or two comparisons. 18140266059SGregory Neil Shapiro In such cases, it is not uncommon for developers to comment out 18240266059SGregory Neil Shapiro the assertion once the code is unit tested. 18340266059SGregory Neil Shapiro Please don't do this: it makes it hard to turn the assertion 18440266059SGregory Neil Shapiro check back on for the purposes of regression testing. 18540266059SGregory Neil Shapiro What you should do instead is make the assertion check conditional 18640266059SGregory Neil Shapiro on one of these predefined debug objects: 18740266059SGregory Neil Shapiro<blockquote> 18840266059SGregory Neil Shapiro SmExpensiveRequire<br> 18940266059SGregory Neil Shapiro SmExpensiveAssert<br> 19040266059SGregory Neil Shapiro SmExpensiveEnsure 19140266059SGregory Neil Shapiro</blockquote> 19240266059SGregory Neil Shapiro By doing this, you bring the cost of the assertion checking code 19340266059SGregory Neil Shapiro back down to a single comparison, unless expensive assertion checking 19440266059SGregory Neil Shapiro has been explicitly enabled. 19540266059SGregory Neil Shapiro By the way, the corresponding debug category names are 19640266059SGregory Neil Shapiro<blockquote> 19740266059SGregory Neil Shapiro sm_check_require<br> 19840266059SGregory Neil Shapiro sm_check_assert<br> 19940266059SGregory Neil Shapiro sm_check_ensure 20040266059SGregory Neil Shapiro</blockquote> 20140266059SGregory Neil Shapiro What activation level should you check for? 20240266059SGregory Neil Shapiro Higher levels correspond to more expensive assertion checks. 20340266059SGregory Neil Shapiro Here are some basic guidelines: 20440266059SGregory Neil Shapiro<blockquote> 20540266059SGregory Neil Shapiro level 1: < 10 basic C operations<br> 20640266059SGregory Neil Shapiro level 2: < 100 basic C operations<br> 20740266059SGregory Neil Shapiro level 3: < 1000 basic C operations<br> 20840266059SGregory Neil Shapiro ... 20940266059SGregory Neil Shapiro</blockquote> 21040266059SGregory Neil Shapiro 21140266059SGregory Neil Shapiro<p> 21240266059SGregory Neil Shapiro Here's a contrived example of both techniques: 21340266059SGregory Neil Shapiro<blockquote><pre> 21440266059SGregory Neil Shapirovoid 21540266059SGregory Neil Shapirow_munge(WIDGET *w) 21640266059SGregory Neil Shapiro{ 21740266059SGregory Neil Shapiro SM_REQUIRE(w != NULL); 21840266059SGregory Neil Shapiro#if SM_CHECK_REQUIRE 21940266059SGregory Neil Shapiro /* 22040266059SGregory Neil Shapiro ** We run this check at level 3 because we expect to check a few hundred 22140266059SGregory Neil Shapiro ** table entries. 22240266059SGregory Neil Shapiro */ 22340266059SGregory Neil Shapiro 22440266059SGregory Neil Shapiro if (sm_debug_active(&SmExpensiveRequire, 3)) 22540266059SGregory Neil Shapiro { 22640266059SGregory Neil Shapiro int i; 22740266059SGregory Neil Shapiro 22840266059SGregory Neil Shapiro for (i = 0; i < WIDGET_MAX; ++i) 22940266059SGregory Neil Shapiro { 23040266059SGregory Neil Shapiro if (w[i] == NULL) 23140266059SGregory Neil Shapiro sm_abort("w_munge: NULL entry %d in widget table", i); 23240266059SGregory Neil Shapiro } 23340266059SGregory Neil Shapiro } 23440266059SGregory Neil Shapiro#endif /* SM_CHECK_REQUIRE */ 23540266059SGregory Neil Shapiro</pre></blockquote> 23640266059SGregory Neil Shapiro 23740266059SGregory Neil Shapiro<h2> Other Guidelines </h2> 23840266059SGregory Neil Shapiro 23940266059SGregory Neil Shapiro You should resist the urge to write SM_ASSERT(0) when the code has 24040266059SGregory Neil Shapiro reached an impossible place. It's better to call sm_abort, because 24140266059SGregory Neil Shapiro then you can generate a better error message. For example, 24240266059SGregory Neil Shapiro<blockquote><pre> 24340266059SGregory Neil Shapiroswitch (foo) 24440266059SGregory Neil Shapiro{ 24540266059SGregory Neil Shapiro ... 24640266059SGregory Neil Shapiro default: 24740266059SGregory Neil Shapiro sm_abort("impossible value %d for foo", foo); 24840266059SGregory Neil Shapiro} 24940266059SGregory Neil Shapiro</pre></blockquote> 25040266059SGregory Neil Shapiro Note that I did not bother to guard the default clause of the switch 25140266059SGregory Neil Shapiro statement with #if SM_CHECK_ASSERT ... #endif, because there is 25240266059SGregory Neil Shapiro probably no performance gain to be had by disabling this particular check. 25340266059SGregory Neil Shapiro<p> 25440266059SGregory Neil Shapiro Avoid including code that has side effects inside of assert macros, 25540266059SGregory Neil Shapiro or inside of SM_CHECK_* guards. You don't want the program to stop 25640266059SGregory Neil Shapiro working if assertion checking is disabled. 25740266059SGregory Neil Shapiro 25840266059SGregory Neil Shapiro<h2> Rationale for Logic Bug Handling </h2> 25940266059SGregory Neil Shapiro 26040266059SGregory Neil Shapiro When a logic bug is detected, our philosophy is to log an error message 26140266059SGregory Neil Shapiro and terminate the program, dumping core if possible. 26240266059SGregory Neil Shapiro It is not a good idea to raise an exception, attempt cleanup, 26340266059SGregory Neil Shapiro or continue program execution. Here's why. 26440266059SGregory Neil Shapiro<p> 26540266059SGregory Neil Shapiro First of all, to facilitate post-mortem analysis, we want to dump core 26640266059SGregory Neil Shapiro on detecting a logic bug, disturbing the process image as little as 26740266059SGregory Neil Shapiro possible before dumping core. We don't want to raise an exception 26840266059SGregory Neil Shapiro and unwind the stack, executing cleanup code, before dumping core, 26940266059SGregory Neil Shapiro because that would obliterate information we need to analyze the cause 27040266059SGregory Neil Shapiro of the abort. 27140266059SGregory Neil Shapiro<p> 27240266059SGregory Neil Shapiro Second, it is a bad idea to raise an exception on an assertion failure 27340266059SGregory Neil Shapiro because this places unacceptable restrictions on code that uses 27440266059SGregory Neil Shapiro the assertion macros. 27540266059SGregory Neil Shapiro The reason is this: the sendmail code must be written so that 27640266059SGregory Neil Shapiro anywhere it is possible for an assertion to be raised, the code 27740266059SGregory Neil Shapiro will catch the exception and clean up if necessary, restoring 27840266059SGregory Neil Shapiro data structure invariants and freeing resources as required. 27940266059SGregory Neil Shapiro If an assertion failure was signalled by raising an exception, 28040266059SGregory Neil Shapiro then every time you added an assertion, you would need to check 28140266059SGregory Neil Shapiro both the function containing the assertion and its callers to see 28240266059SGregory Neil Shapiro if any exception handling code needed to be added to clean up properly 28340266059SGregory Neil Shapiro on assertion failure. That is far too great a burden. 28440266059SGregory Neil Shapiro<p> 28540266059SGregory Neil Shapiro It is a bad idea to attempt cleanup upon detecting a logic bug 28640266059SGregory Neil Shapiro for several reasons: 28740266059SGregory Neil Shapiro<ul> 28840266059SGregory Neil Shapiro<li>If you need to perform cleanup actions in order to preserve the 28940266059SGregory Neil Shapiro integrity of the data that the program is handling, then the 29040266059SGregory Neil Shapiro program is not fault tolerant, and needs to be redesigned. 29140266059SGregory Neil Shapiro There are several reasons why a program might be terminated unexpectedly: 29240266059SGregory Neil Shapiro the system might crash, the program might receive a signal 9, 29340266059SGregory Neil Shapiro the program might be terminated by a memory fault (possibly as a 29440266059SGregory Neil Shapiro side effect of earlier data structure corruption), and the program 29540266059SGregory Neil Shapiro might detect a logic bug and terminate itself. Note that executing 29640266059SGregory Neil Shapiro cleanup actions is not feasible in most of the above cases. 29740266059SGregory Neil Shapiro If the program has a fault tolerant design, then it will not lose 29840266059SGregory Neil Shapiro data even if the system crashes in the middle of an operation. 29940266059SGregory Neil Shapiro<p> 30040266059SGregory Neil Shapiro<li>If the cause of the logic bug is earlier data structure corruption, 30140266059SGregory Neil Shapiro then cleanup actions intended to preserve the integrity of the data 30240266059SGregory Neil Shapiro that the program is handling might cause more harm than good: they 30340266059SGregory Neil Shapiro might cause information to be corrupted or lost. 30440266059SGregory Neil Shapiro<p> 30540266059SGregory Neil Shapiro<li>If the program uses threads, then cleanup is much more problematic. 30640266059SGregory Neil Shapiro Suppose that thread A is holding some locks, and is in the middle of 30740266059SGregory Neil Shapiro modifying a shared data structure. The locks are needed because the 30840266059SGregory Neil Shapiro data structure is currently in an inconsistent state. At this point, 30940266059SGregory Neil Shapiro a logic bug is detected deep in a library routine called by A. 31040266059SGregory Neil Shapiro How do we get all of the running threads to stop what they are doing 31140266059SGregory Neil Shapiro and perform their thread-specific cleanup actions before terminating? 31240266059SGregory Neil Shapiro We may not be able to get B to clean up and terminate cleanly until 31340266059SGregory Neil Shapiro A has restored the invariants on the data structure it is modifying 31440266059SGregory Neil Shapiro and releases its locks. So, we raise an exception and unwind the stack, 31540266059SGregory Neil Shapiro restoring data structure invariants and releasing locks at each level 31640266059SGregory Neil Shapiro of abstraction, and performing an orderly shutdown. There are certainly 31740266059SGregory Neil Shapiro many classes of error conditions for which using the exception mechanism 31840266059SGregory Neil Shapiro to perform an orderly shutdown is appropriate and feasible, but there 31940266059SGregory Neil Shapiro are also classes of error conditions for which exception handling and 32040266059SGregory Neil Shapiro orderly shutdown is dangerous or impossible. The abnormal program 32140266059SGregory Neil Shapiro termination system is intended for this second class of error conditions. 32240266059SGregory Neil Shapiro If you want to trigger orderly shutdown, don't call sm_abort: 32340266059SGregory Neil Shapiro raise an exception instead. 32440266059SGregory Neil Shapiro</ul> 32540266059SGregory Neil Shapiro<p> 32640266059SGregory Neil Shapiro Here is a strategy for making sendmail fault tolerant. 32740266059SGregory Neil Shapiro Sendmail is structured as a collection of processes. The "root" process 32840266059SGregory Neil Shapiro does as little as possible, except spawn children to do all of the real 32940266059SGregory Neil Shapiro work, monitor the children, and act as traffic cop. 33040266059SGregory Neil Shapiro We use exceptions to signal expected but infrequent error conditions, 33140266059SGregory Neil Shapiro so that the process encountering the exceptional condition can clean up 33240266059SGregory Neil Shapiro and keep going. (Worker processes are intended to be long lived, in 33340266059SGregory Neil Shapiro order to minimize forking and increase performance.) But when a bug 33440266059SGregory Neil Shapiro is detected in a sendmail worker process, the worker process does minimal 33540266059SGregory Neil Shapiro or no cleanup and then dies. A bug might be detected in several ways: 33640266059SGregory Neil Shapiro the process might dereference a NULL pointer, receive a signal 11, 33740266059SGregory Neil Shapiro core dump and die, or an assertion might fail, in which case the process 33840266059SGregory Neil Shapiro commits suicide. Either way, the root process detects the death of the 33940266059SGregory Neil Shapiro worker, logs the event, and spawns another worker. 34040266059SGregory Neil Shapiro 34140266059SGregory Neil Shapiro<h2> Rationale for Naming Conventions </h2> 34240266059SGregory Neil Shapiro 34340266059SGregory Neil Shapiro The names "require" and "ensure" come from the writings of Bertrand Meyer, 34440266059SGregory Neil Shapiro a prominent evangelist for assertion checking who has written a number of 34540266059SGregory Neil Shapiro papers about the "Design By Contract" programming methodology, 34640266059SGregory Neil Shapiro and who created the Eiffel programming language. 34740266059SGregory Neil Shapiro Many other assertion checking packages for C also have "require" and 34840266059SGregory Neil Shapiro "ensure" assertion types. In short, we are conforming to a de-facto 34940266059SGregory Neil Shapiro standard. 35040266059SGregory Neil Shapiro<p> 35140266059SGregory Neil Shapiro We use the names <tt>SM_REQUIRE</tt>, <tt>SM_ASSERT</tt> 35240266059SGregory Neil Shapiro and <tt>SM_ENSURE</tt> in preference to to <tt>REQUIRE</tt>, 35340266059SGregory Neil Shapiro <tt>ASSERT</tt> and <tt>ENSURE</tt> because at least two other 35440266059SGregory Neil Shapiro open source libraries (libisc and libnana) define <tt>REQUIRE</tt> 35540266059SGregory Neil Shapiro and <tt>ENSURE</tt> macros, and many libraries define <tt>ASSERT</tt>. 35640266059SGregory Neil Shapiro We want to avoid name conflicts with other libraries. 35740266059SGregory Neil Shapiro 35840266059SGregory Neil Shapiro</body> 35940266059SGregory Neil Shapiro</html> 360