Skip to content

Shallow Copies

Reini Urban edited this page Jan 4, 2021 · 3 revisions

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.

Clone this wiki locally