Last active
March 14, 2026 22:39
-
-
Save rexim/48d7087bfc8ba2c28a8b0b3aa3183558 to your computer and use it in GitHub Desktop.
Source code from the "Insane Shadow Data Trick in C" YouTube video https://www.youtube.com/watch?v=gtk3RZHwJUA
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // cc -o arr arr.c && ./arr | |
| #include <assert.h> | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| typedef struct { | |
| size_t count; | |
| size_t capacity; | |
| } Header; | |
| #define ARR_INIT_CAPACITY 1 | |
| #define arr_push(arr, x) \ | |
| do { \ | |
| if (arr == NULL) { \ | |
| Header *header = malloc(sizeof(*arr)*ARR_INIT_CAPACITY + sizeof(Header)); \ | |
| header->count = 0; \ | |
| header->capacity = ARR_INIT_CAPACITY; \ | |
| arr = (void*)(header + 1); \ | |
| } \ | |
| Header *header = (Header*)(arr) - 1; \ | |
| if (header->count >= header->capacity) { \ | |
| header->capacity *= 2; \ | |
| header = realloc(header, sizeof(*arr)*header->capacity + sizeof(Header)); \ | |
| arr = (void*)(header + 1); \ | |
| } \ | |
| (arr)[header->count++] = (x); \ | |
| } while(0) | |
| #define arr_len(arr) ((Header*)(arr) - 1)->count | |
| #define arr_free(arr) free((Header*)(arr) - 1) | |
| int main() | |
| { | |
| float *numbers = NULL; | |
| arr_push(numbers, 69); | |
| arr_push(numbers, 420); | |
| arr_push(numbers, 1337); | |
| arr_push(numbers, 80085); | |
| if (1) arr_push(numbers, 111); else arr_push(numbers, 222); | |
| for (size_t i = 0; i < arr_len(numbers); ++i) { | |
| printf("%f\n", numbers[i]); | |
| } | |
| arr_free(numbers); | |
| return 0; | |
| } | |
| ////////////////////////////// | |
| #if 0 | |
| #define STB_DS_IMPLEMENTATION | |
| #include "stb_ds.h" | |
| typedef struct { | |
| const char *key; | |
| size_t value; | |
| } Item; | |
| Item *table = NULL; | |
| int main2() | |
| { | |
| shput(table, "foo", 69); | |
| shput(table, "bar", 420); | |
| shput(table, "baz", 1337); | |
| table[shgeti(table, "bar")].value = 80085; | |
| for (int i = 0; i < shlen(table); ++i) { | |
| printf("%s => %zu\n", table[i]); | |
| } | |
| return 0; | |
| } | |
| #endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
interesting, even stranger if i do something like;
https://godbolt.org/z/34qE15hef
that also works with 2 int's as fields of the struct. i have not looked into the assembler to see what is going on under the covers yet between the difference impl.s etc. cheers.