-
Notifications
You must be signed in to change notification settings - Fork 8
Shallow Copies
CTL passes all POD types T
by value (non-structs) to various container functions, giving an easy to use syntax for modifying a container with a single line:
#define POD
vec_int_push_back(&a, 1);
The following is valid:
int value = 1;
vec_int_push_back(&a, value);
But non-POD types with memory ownership, functions consume (shallow copy) types with memory ownership:
#undef POD
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);
Non-immediate, non-POD values, like structs or unions, as digit d
are 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.
So its best to use this idiom on a single line:
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, POD functions with type T
consume their type, and are best used with the immediate value outlined above.
Other libraries store copies of all values internally, we do not.