Since release 2.0-beta2, Libretto has provided truly abstract data
types. Formerly, the members of structures were visible to Libretto's
users; only good programming style prevented looking at `private'
members. Now all members are private: the public header file contains
only forward declarations for structures. The few functions that
expected the user to allocate sufficient memory for a structure have
been deemed unnecessary and therefore removed. New functions have been
added to access the members that were previously considered `public'.
The principal advantage of this change is that the layout and size of a
structure are no longer binary interfaces provided by the library.
User-supplied arguments to functions are range-checked using ‘assert’.
This means that if, for example, the library is given a null pointer in an
inappropriate place, the program will quit.1
Containers parametrise the stored type either in terms of
‘sizeof’2 or by simply
using a generic pointer (‘void *’).
Functions that internally allocate or re-allocate memory return an
‘int’ status value, where 0 indicates success and -1
indicates failure.
All functions are designed to allocate and reallocate memory dynamically,
wherever necessary. This means that on a machine with plenty of swap space,
your program is unlikely to encounter arbitrary limits. (It also prevents
buffer-overflow exploits for buggy setuid programs.)
`Allocate-or-die' semantics are the default throughout. This can
substantially simplify the programming model in user code. A `report
failures on out-of-memory' mode is selectable at runtime.
Footnotes
[1] This may change in
the future, given sufficient demand.
[2] This is one of the features of ‘Darray’ that
makes it deprecated. When ‘Darray’ has a replacement, no new code
will need to parametrise a container by ‘sizeof’.