ALPHA: breaking changes expected. What that means
NanoC

Generic vector

One macro generates a typed growable vector per element type: generics without a runtime.

NanoC
+ <stdio.h>
+ <stdlib.h>
# One macro stamps out a typed growable vector per element type: generics without a runtime.
@m vec($T, $name, $push)
  s $name
    data: *`$ T`
    len,cap: i32
  f $push(v: *$name, x: $T)
    if v->len == v->cap
      v->cap = v->cap ? v->cap * 2 : 4
      v->data = realloc(v->data, v->cap * sizeof($T))
    v->data[v->len++] = x
@vec(int, IntVec, IntVec_push)
@vec(double, DoubleVec, DoubleVec_push)
f main()
  a: IntVec = {0}
  b: DoubleVec = {0}
  for i := 0; i < 10; i++
    IntVec_push(&a, i * 3)
    DoubleVec_push(&b, i / 4.0)
  printf("ints %d, last %d, cap %d\n", a.len, a.data[a.len - 1], a.cap)
  printf("doubles %d, last %g\n", b.len, b.data[b.len - 1])
  free(a.data)
  free(b.data)
  < 0
C
#include <stdio.h>
#include <stdlib.h>

typedef struct IntVec IntVec;
struct IntVec {
    $ T *data;
    int len,cap;
};

void IntVec_push(IntVec *v, int x) {
    if (v->len == v->cap) {
        v->cap = v->cap ? v->cap * 2 : 4;
        v->data = realloc(v->data, v->cap * sizeof(int));
    }
    v->data[v->len++] = x;
}

typedef struct DoubleVec DoubleVec;
struct DoubleVec {
    $ T *data;
    int len,cap;
};

void DoubleVec_push(DoubleVec *v, double x) {
    if (v->len == v->cap) {
        v->cap = v->cap ? v->cap * 2 : 4;
        v->data = realloc(v->data, v->cap * sizeof(double));
    }
    v->data[v->len++] = x;
}

int main(void) {
    IntVec a = {0};
    DoubleVec b = {0};
    for (int i = 0; i < 10; i++) {
        IntVec_push(&a, i * 3);
        DoubleVec_push(&b, i / 4.0);
    }
    printf("ints %d, last %d, cap %d\n", a.len, a.data[a.len - 1], a.cap);
    printf("doubles %d, last %g\n", b.len, b.data[b.len - 1]);
    free(a.data);
    free(b.data);
    return 0;
}

What it shows

@m, code generation

Edit in the playgroundSource on GitHub