auto p = (thing_t *)malloc(sizeof(thing_t));
While that line of code is DRY, it doesn't avoid casting "void *" to "thing_t *".
While that line of code is DRY, it doesn't avoid casting "void *" to "thing_t *".