<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title>Using Wrapper Functions</title>
</head>
<body>
<div class="Section1">
<h1>Using Wrapper Functions</h1>
<p>The propose of this document is to provide an example of
how to use wrapper functions to create programs that are
more robust and that Splint can check more
effectively. The C standard library function realloc
has complex semantics and is easy to use incorrectly.
Still, it is a popular function, and we are frequently
asked how to use Splint to check code that uses
realloc. We hope to answer these questions in this
section. Additionally, we hope this example will
provide insight into other ways to work around some of the
limitations of Splint’s checking, and serve as a
template for users wishing to create their own wrapper
functions.</p>
<p>Splint cannot currently describe general functions where
some of the attributes are dependent on one or more of the
possible return values. Often, functions are defined
to modify their outputs, and perhaps allocate storage, but
can also return an error indication, in which case none of
the modifications or allocations will take place.</p>
<p>One very common example of this is the C standard
library function realloc( void *pointer, size_t
size). When realloc succeeds, the pointer passed to
it is no longer valid. The returned pointer points to
available storage with the specified size, and the values
are copied from the leading portion of the original storage
indicated by the pointer passed to the function. When
realloc returns a NULL pointer, and more than zero bytes
were supposed to be allocated, no new storage has been
allocated. The original pointer passed in is not
deallocated and its contents are still accessible.
(Under ANSI C '89 and later, malloc and realloc may return
NULL if asked for zero bytes. In this case, realloc
would release the old storage.)</p>
<p>If you use realloc, -usereleased can be used to suppress
warnings. However, this may result in legitimate
warnings for other errors being suppressed as well.
If you don't mind crafting your code to work around
Splint's quirks, you can isolate this difficult-to-describe
behavior to a single function that's easy to verify by
inspection, and use that function elsewhere. For
example:</p>
/*@-usereleased@*/<br>
static /*@null@*/ void *<br>
grow_or_free (/*@only@*/ void *ptr,
size_t newsize)<br>
/*@*/<br>
{<br>
void
*newptr;<br>
newptr =
realloc (ptr, newsize);<br>
if (newptr ==
NULL && newsize != 0) {<br>
/* Splint would complain,<br>
but this is correct. */<br>
free (ptr);<br>
return NULL;<br>
}<br>
return
newptr;<br>
}<br>
/*@=usereleased@*/<br>
<p>It would also be possible to use a function that always
returns a valid pointer, and separately indicates whether
it managed to change the size to that desired by the
caller.</p>
</div>
</body>
</html>
syntax highlighted by Code2HTML, v. 0.9.1