HiveBrain v1.2.0
Get Started
← Back to all entries
patterncMinor

Generic vector implementation in C using macros

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
genericmacrosusingimplementationvector

Problem

I while ago I experimented with macros in C and came up with the idea of implementing a generic vector library using macros.

This code uses the non standard typeof extension that returns the type of an expression.

```
#ifndef VECTOR_H
#define VECTOR_H

#include
#include

#define VECTOR_OF(T) struct { \
typeof (T) *data; \
unsigned size; \
unsigned capacity; \
}

#define VECTOR_INIT_ASSIGN(VEC, VAL) do { \
typeof (VEC) *vec = &(VEC); \
typeof (VAL) val = (VAL); \
vec->data = malloc(sizeof *vec->data); \
vec->size = vec->capacity = 1; \
vec->data[0] = val; \
} while (0)

#define VECTOR_INIT_ASSIGN_N(VEC, N, VAL) do { \
typeof (VEC) *vec = &(VEC); \
unsigned n = (N); \
typeof (VAL) val = (VAL); \
vec->data = malloc(n sizeof vec->data); \
vec->size = vec->capacity = n; \
while (n-- > 0) \
vec->data[n] = val; \
} while (0)

#define VECTOR_INIT_ASSIGN_PTR(VEC, N, PTR) do { \
typeof (VEC) *vec = &(VEC); \
unsigned n = (N); \
typeof (PTR) ptr = (PTR); \
vec->data = malloc(n sizeof vec->data); \
vec->size = vec->capacity = n; \
while (n-- > 0) \
vec->data[n] = ptr[n]; \
} while (0)

#define VECTOR_INIT_RESERVE(VEC, N) do { \
typeof (VEC) *vec = &(VEC); \
unsigned n = (N); \
vec->data = malloc(n sizeof vec->data); \
vec->size = 0; \
vec->capacity = n; \
} while (0)

#define VECTOR_INIT(VEC) VECTOR_INIT_RESERVE((VEC), 1)

#define VECTOR_SIZE(VEC) (VEC).size

#define VECTOR_EMPTY(VEC) ((VEC).size == 0)

#define VECTOR_CAPACITY(VEC) (VEC).capacity

#define VECTOR_RESERVE(VEC, N) do { \
typeof (VEC) *vec = &(VEC); \
typeof (N) n = (N); \
if (vec->capacity data = realloc(n sizeof vec->data); \
vec->capacity = n; \
} \
} while (0)

#define VECTOR_RESIZE(VEC, N, VAL) do { \
typeof (VEC) *vec = &(VEC); \
unsigned n = (N), i; \
typeof (VAL) val = (VAL); \
if (n > vec->capacity) \
vec->data = realloc(vec-

Solution

I never thought macro code could be pretty, but this is actually very readable. However, why do you wrap your macros with do-while blocks? I would do away with inline code and prefer to use functions. First of all, they would be easier for the compiler to deal with, and it could then inline the functions as it saw fit.

Second, they would be easier for you to deal with. You could initialize the functions by calling a macro with a type argument. If the generated function names are predictable, you could then call the functions themselves, which provides the benefit of code completion and documentation.

Context

StackExchange Code Review Q#101816, answer score: 2

Revisions (0)

No revisions yet.