aboutsummaryrefslogtreecommitdiff
path: root/test/macro_demo.c
blob: 072ec026cf4b97c1d2933939178beb41aaff7c77 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// a playground for the macro unwrapper. open this file in hsdbg's source view,
// then hover any highlighted macro for a preview and click it to step through
// the expansion one layer at a time in the macros panel.

#include <stdio.h>

// object-like macros that lean on each other, so unrolling takes real layers:
// KIB -> (1 << 10), MIB -> (KIB * KIB) -> ((1 << 10) * (1 << 10)), and so on
#define KIB (1 << 10)
#define MIB (KIB * KIB)
#define GIB (MIB * KIB)

// function-like macros, including one built out of another
#define SQUARE(x) ((x) * (x))
#define CUBE(x)   (SQUARE(x) * (x))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define CLAMP(v, lo, hi) MAX(lo, MIN(v, hi))
#define MIN(a, b) ((a) < (b) ? (a) : (b))

// the classic stringize-through-indirection: STR sees its argument raw, XSTR
// expands it first. hover both to see "VERSION" vs "3"
#define VERSION 3
#define STR(x)  #x
#define XSTR(x) STR(x)

// token pasting, direct and through a level of indirection
#define CAT(a, b)  a ## b
#define XCAT(a, b) CAT(a, b)

// a variadic logging macro
#define LOG(level, fmt, ...) fprintf(stderr, "[" level "] " fmt "\n", __VA_ARGS__)

int main(void)
{
    int width  = 5;
    int height = 9;

    printf("a mebibyte is %d bytes\n", MIB);
    printf("square %d, cube %d\n", SQUARE(width), CUBE(width));
    printf("clamped %d\n", CLAMP(height, 0, 8));
    printf("building version %s\n", XSTR(VERSION));

    int XCAT(sum_, 1) = width + height;
    LOG("info", "sum is %d", XCAT(sum_, 1));

    return 0;
}