Skip to content

Instantly share code, notes, and snippets.

@rexim
Last active March 4, 2026 12:57
Show Gist options
  • Select an option

  • Save rexim/48d7087bfc8ba2c28a8b0b3aa3183558 to your computer and use it in GitHub Desktop.

Select an option

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
// 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
@lduguid
Copy link

lduguid commented Feb 27, 2026

Just curious concerning printf("%s => %zu\n", table[i]); , could this be undefined behavior? i guess due to the how the fields of the Item structures field values are laid out in contiguous memory, and printf being variadic , this will print out the fields as specified by the printf format specifiers and all seems good and it is good =) But if this is the case, I am slightly concerned that your cc compilation did not spit out a warning? Great show!

@drehren
Copy link

drehren commented Mar 3, 2026

Had the same doubt.. seems to be something gcc does as msvc doesn't print the values. It also only seems to work if the first element is a char array, because passing a struct with two numbers doesn't work.
You can play here https://godbolt.org/z/d8Eqaecxj

@lduguid
Copy link

lduguid commented Mar 3, 2026

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment