-
Notifications
You must be signed in to change notification settings - Fork 56
Shallow Copies
CTL passes all types T
by value to various container functions, giving an easy to use syntax for modifying a container with a single line:
vec_int_push_back(&a, 1);
The following is valid:
int value = 1;
vec_int_push_back(&a, value);
But types with memory ownership, functions consume (shallow copy) types with memory ownership:
typedef struct { int* x; } digit;
digit
digit_init(int value)
{
digit d = { malloc(sizeof(int)) };
d.x = value;
return d;
}
digit d = digit_init(42);
vec_digit_push_back(&a, d);
digit d
is copied by value (shallow copied) and inserted as a new element into the vec
container. A free on d
after its insertion
will cause a heap use after free
runtime fault, or potentially a double free
runtime fault. Syntax vec_int_push_back(&a, 1)
, where the function call and type resides on the same line, aids in preventing heap use after free
runtime faults, or double free
runtime faults with memory ownership types, by conjoining the construction of the type with its container call, as below:
vec_digit_push_back(&a, digit_init(42));
All CTL functions are marked as static inline
. Given gcc
compiles with optimization settings -O1
or higher, superfluous copies by value will largely be eliminated. In summary, functions with type T
(see below) consume their type, and are best used with the single line syntax outlined above:
static inline void
JOIN(A, resize)(A* self, size_t size, T value);
static inline void
JOIN(A, assign)(A* self, size_t size, T value);
static inline void
JOIN(A, push_back)(A* self, T value);
static inline void
JOIN(A, push_front)(A* self, T value);