Go forward to Expressions.
Go backward to Proto.
Go up to Top.
Variable-Sized Object Representation
************************************
One of the first goals of the GNU C++ library is to enrich the kinds
of basic classes that may be considered as (nearly) "built into" C++. A
good deal of the inspiration for these efforts is derived from
considering features of other type-rich languages, particularly Common
Lisp and Scheme. The general characteristics of most class and friend
operators and functions supported by these classes has been heavily
influenced by such languages.
Four of these types, Strings, Integers, BitSets, and BitStrings (as
well as associated and/or derived classes) require representations
suitable for managing variable-sized objects on the free-store. The
basic technique used for all of these is the same, although various
details necessarily differ from class to class.
The general strategy for representing such objects is to create
chunks of memory that include both header information (e.g., the size
of the object), as well as the variable-size data (an array of some
sort) at the end of the chunk. Generally the maximum size of an object
is limited to something less than all of addressable memory, as a
safeguard. The minimum size is also limited so as not to waste
allocations expanding very small chunks. Internally, chunks are
allocated in blocks well-tuned to the performance of the `new' operator.
Class elements themselves are merely pointers to these chunks. Most
class operations are performed via inline "translation" functions that
perform the required operation on the corresponding representation.
However, constructors and assignments operate by copying entire
representations, not just pointers.
No attempt is made to control temporary creation in expressions and
functions involving these classes. Users of previous versions of the
classes will note the disappearance of both "Tmp" classes and reference
counting. These were dropped because, while they did improve
performance in some cases, they obscure class mechanics, lead
programmers into the false belief that they need not worry about such
things, and occasionally have paradoxical behavior.
These variable-sized object classes are integrated as well as
possible into C++. Most such classes possess converters that allow
automatic coercion both from and to builtin basic types. (e.g., char*
to and from String, long int to and from Integer, etc.). There are
pro's and con's to circular converters, since they can sometimes lead
to the conversion from a builtin type through to a class function and
back to a builtin type without any special attention on the part of the
programmer, both for better and worse.
Most of these classes also provide special-case operators and
functions mixing basic with class types, as a way to avoid constructors
in cases where the operations do not rely on anything special about the
representations. For example, there is a special case concatenation
operator for a String concatenated with a char, since building the
result does not rely on anything about the String header. Again, there
are arguments both for and against this approach. Supporting these cases
adds a non-trivial degree of (mainly inline) function proliferation, but
results in more efficient operations. Efficiency wins out over parsimony
here, as part of the goal to produce classes that provide sufficient
functionality and efficiency so that programmers are not tempted to try
to manipulate or bypass the underlying representations.