Skip to content

Instantly share code, notes, and snippets.

@CTurt
Last active September 3, 2017 13:13
Show Gist options
  • Save CTurt/fff6a44e87ed1b03bfce3d92f4e7965d to your computer and use it in GitHub Desktop.
Save CTurt/fff6a44e87ed1b03bfce3d92f4e7965d to your computer and use it in GitHub Desktop.
C named array elements
/*
Abusing C preprocessor to allow you declare enumerator values for each item of an array, inline of the array definition - so that you don't have to repeat list twice like this:
enum {
ITEM_ONE,
ITEM_TWO,
...
};
struct type array[] = {
[ITEM_ONE] = { x },
[ITEM_TWO] = { x },
...
};
Need to disable `-Winitializer-overrides` so compile with:
clang item.c -Wno-initializer-overrides -o item
or you could just disable it for the array definition:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Winitializer-overrides"
struct type array[] = { ... };
#pragma clang diagnostic pop
Output:
one (6, 8)
two (9, 2)
three (77, 2)
four (4, 18)
- CTurt
*/
#include <stdio.h>
// If first element in struct is not a pointer remove `void *` cast
#define BEGIN_ARRAY(prefix) [0] = { (void *)(enum { TABLE_START_##prefix = __LINE__ })0 }
#define ARRAY_ENTRY(prefix, n, f, ...) [__LINE__ - TABLE_START_##prefix - 1] = { f?:(enum { prefix##_##n = __LINE__ - TABLE_START_##prefix - 1 })0, ##__VA_ARGS__ }
struct item {
char *a;
int b;
int c;
};
struct item itemArray[] = {
BEGIN_ARRAY(ITEM),
ARRAY_ENTRY(ITEM, ONE, .a = "one", .b = 6, .c = 8),
ARRAY_ENTRY(ITEM, TWO, .a = "two", .b = 9, .c = 2),
ARRAY_ENTRY(ITEM, THREE, .a = "three", .b = 77, .c = 2),
ARRAY_ENTRY(ITEM, FOUR, .a = "four", .b = 4, .c = 18),
};
void info(struct item *item) {
printf("%s (%d, %d)\n", item->a, item->b, item->c);
}
int main(void) {
info(&itemArray[ITEM_ONE]);
info(&itemArray[ITEM_TWO]);
info(&itemArray[ITEM_THREE]);
info(&itemArray[ITEM_FOUR]);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment