Base Tools
A handful of tools are available in the include/emp/base/ folder in Empirical. These mimic basic functionality available in C++ or its standard library, but provide extra protection against common memory use errors and additional information to the developer. These protections can be turned off by comiling with -DNDEBUG.
base/assert.h
This file adds an emp_assert
macro that can handle all of the same
functionality as the standard library assert, but with additional
features. Specifically, additional arguments may be added that are
printed when the assert is triggered. For example, the line
emp_assert(i < 10, i);
if triggered, would print something to the effect of
Assert Error (In assert.cc line 6): i < 10
i: [1844674]
Abort
Indicating that not only was i >= 10
, but its current value is
1844674.
If compiled as part of a web app (with emscripten) emp_assert
: will
automatically use the JavaScript Alert function to indicate any assert
failures. Asserts are all disabled (fully removed from compiled code) if
compiled using the NDEBUG
option (for most compilers, this
deactivation is accomplished by using the -DNDEBUG
flag at compile
time.)
base/array.h and base/vector.h
These files setup the emp::array<...>
and emp::vector<...>
template
objects, which behave almost identically to std::array<...>
and
std::vector<...>
, respectively. The one difference is that they do
bounds checking when they are indexed into or specific size matters. As
with asserts, these additional bounds checks are removed when compiled
with the NDEBUG
option.
base/Ptr.h
The emp::Ptr<...>
template provides an alternate method of building
pointers, but with the ability to turn on additional debugging
facilities; unlike assert, array, and vector, no debugging is performed
by default due to substantial run-time costs. For example declaring a
variable as emp::Ptr<int>
is the same as declaring it int *
.
If the EMP_TRACK_MEM
option is set (-DEMP_TRACK_MEM
compiler flag)
then all pointer usage is tracked and many simple memory errors will be
identified during execution, such as using or deleting an unallocated
pointer.
Most usage of the Ptr
class is identical to raw pointers, including
all operator. Differences include:
Rather than using
new TYPE
to allocate a new pointer, useemp::NewPtr<TYPE>
If allocating an array, use
emp::NewArrayPtr<TYPE>(SIZE)
To delete use the
.Delete()
or.DeleteArray()
member function (notdelete
ordelete[]
).To cast one
Ptr
type to another, use the.Cast<TYPE>
member function.To dynamic cast (double-checking types and returning
nullptr
on failure), use.DynamicCast<TYPE>
To convert a Ptr
-allocated pointer to the raw form, use the Raw()
member function. Make sure that any pointer allocated as a Ptr
type is
also freed as a Ptr
type.