preprocessor-toolchain · advanced · ~15 min

C11 Generic Macro Dispatcher

Implement type-generic compile-time dispatch using C11 _Generic expressions.

Challenge

C11 introduced _Generic expressions to provide compile-time type-based function dispatch without runtime overhead or void-pointer type erasure.

Your Task

Implement type-specific serializers and a _Generic dispatcher macro:

int serialize_int(int val, char *buf, size_t cap);
int serialize_double(double val, char *buf, size_t cap);
int serialize_string(const char *val, char *buf, size_t cap);

#define SERIALIZE(x, buf, cap) ...

Rules

  1. serialize_int: formats integer using snprintf(buf, cap, "%d", val). Returns written length or -1 on truncation/error.
  2. serialize_double: formats double using snprintf(buf, cap, "%.2f", val). Returns written length or -1 on truncation/error.
  3. serialize_string: copies string using snprintf(buf, cap, "%s", val ? val : "NULL"). Returns written length or -1 on truncation/error.
  4. SERIALIZE(x, buf, cap): uses _Generic on (x) to dispatch to serialize_int for int, serialize_double for double, serialize_string for char* and const char*.

Example

char out[32];
SERIALIZE(42, out, sizeof(out)); // out == "42"
SERIALIZE(3.1415, out, sizeof(out)); // out == "3.14"
SERIALIZE("test", out, sizeof(out)); // out == "test"

Input format

x: int, double, or string literal; buf: output buffer; cap: capacity.

Output format

Returns characters written or -1 on truncation.

Constraints

Must use C11 _Generic selection macro.

Starter code

#include <stddef.h>
#include <stdio.h>

int serialize_int(int val, char *buf, size_t cap) {
    (void)val; (void)buf; (void)cap; return -1;
}
int serialize_double(double val, char *buf, size_t cap) {
    (void)val; (void)buf; (void)cap; return -1;
}
int serialize_string(const char *val, char *buf, size_t cap) {
    (void)val; (void)buf; (void)cap; return -1;
}

#define SERIALIZE(x, buf, cap) 0

Common mistakes

Forgetting const char* branch in _Generic; missing parentheses around macro parameters.

Edge cases to handle

Truncation returns -1; cap == 0 returns -1; NULL string formats as NULL.

Background lessons

Solve this exercise in the browser editor — compile and run against the test harness, no setup required.