diff options
Diffstat (limited to 'manual/assert.texi')
-rw-r--r-- | manual/assert.texi | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/manual/assert.texi b/manual/assert.texi new file mode 100644 index 0000000..1095dc4 --- /dev/null +++ b/manual/assert.texi @@ -0,0 +1,113 @@ +@node Consistency Checking, Mathematics, Low-Level Terminal Interface, Top +@chapter Explicitly Checking Internal Consistency +@cindex consistency checking +@cindex impossible events +@cindex assertions + +When you're writing a program, it's often a good idea to put in checks +at strategic places for ``impossible'' errors or violations of basic +assumptions. These kinds of checks are helpful in debugging problems +with the interfaces between different parts of the program, for example. + +@pindex assert.h +The @code{assert} macro, defined in the header file @file{assert.h}, +provides a convenient way to abort the program while printing some +debugging information about where in the program the error was detected. + +@vindex NDEBUG +Once you think your program is debugged, you can disable the error +checks performed by the @code{assert} macro by recompiling with the +macro @code{NDEBUG} defined. This means you don't actually have to +change the program source code to disable these checks. + +But disabling these consistency checks is undesirable unless they make +the program significantly slower. All else being equal, more error +checking is good no matter who is running the program. A wise user +would rather have a program crash, visibly, than have it return nonsense +without indicating anything might be wrong. + +@comment assert.h +@comment ANSI +@deftypefn Macro void assert (int @var{expression}) +Verify the programmer's belief that @var{expression} should be nonzero +at a certain point in the program. + +If @code{NDEBUG} is not defined, @code{assert} tests the value of +@var{expression}. If it is false (zero), @code{assert} aborts the +program (@pxref{Aborting a Program}) after printing a message of the +form: + +@smallexample +@file{@var{file}}:@var{linenum}: @var{function}: Assertion `@var{expression}' failed. +@end smallexample + +@noindent +on the standard error stream @code{stderr} (@pxref{Standard Streams}). +The filename and line number are taken from the C preprocessor macros +@code{__FILE__} and @code{__LINE__} and specify where the call to +@code{assert} was written. When using the GNU C compiler, the name of +the function which calls @code{assert} is taken from the built-in +variable @code{__PRETTY_FUNCTION__}; with older compilers, the function +name and following colon are omitted. + +If the preprocessor macro @code{NDEBUG} is defined before +@file{assert.h} is included, the @code{assert} macro is defined to do +absolutely nothing. Even the argument expression @var{expression} is +not evaluated, so you should avoid calling @code{assert} with arguments +that involve side effects. + +For example, @code{assert (++i > 0);} is a bad idea, because @code{i} +will not be incremented if @code{NDEBUG} is defined. +@end deftypefn + +Sometimes the ``impossible'' condition you want to check for is an error +return from an operating system function. Then it is useful to display +not only where the program crashes, but also what error was returned. +The @code{assert_perror} macro makes this easy. + +@comment assert.h +@comment GNU +@deftypefn Macro void assert_perror (int @var{errnum}) +Similar to @code{assert}, but verifies that @var{errnum} is zero. + +If @code{NDEBUG} is defined, @code{assert_perror} tests the value of +@var{errnum}. If it is nonzero, @code{assert_perror} aborts the program +after a printing a message of the form: + +@smallexample +@file{@var{file}}:@var{linenum}: @var{function}: @var{error text} +@end smallexample + +@noindent +on the standard error stream. The file name, line number, and function +name are as for @code{assert}. The error text is the result of +@w{@code{strerror (@var{errnum})}}. @xref{Error Messages}. + +Like @code{assert}, if @code{NDEBUG} is defined before @file{assert.h} +is included, the @code{assert_perror} macro does absolutely nothing. It +does not evaluate the argument, so @var{errnum} should not have any side +effects. It is best for @var{errnum} to be a just simple variable +reference; often it will be @code{errno}. + +This macro is a GNU extension. +@end deftypefn + +@strong{Usage note:} The @code{assert} facility is designed for +detecting @emph{internal inconsistency}; it is not suitable for +reporting invalid input or improper usage. + +The information in the diagnostic messages provided by the @code{assert} +macro is intended to to help you, the programmer, track down the cause +of a bug, but is not really useful in telling a user of your program why +his or her input was invalid or why a command could not be carried out. +So you can't use @code{assert} to print the error messages for these +eventualities. + +What's more, your program should not abort when given invalid input, as +@code{assert} would do---it should exit with nonzero status after +printing its error messages, or perhaps read another command or move +on to the next input file. + +@xref{Error Messages}, for information on printing error messages for +problems that @emph{do not} represent bugs in the program. + |