Created
February 22, 2020 05:53
-
-
Save dhilst/d5f3ca90a12840b4f17981f4e15674bd to your computer and use it in GitHub Desktop.
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
#include <assert.h> | |
#include <string.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <stddef.h> | |
/* | |
* You can get the offset of a member on a struct by dereferencing that member on | |
* address 0 of such structure. | |
*/ | |
#define offset_of(type, member) ((unsigned long) &((type *)0)->member) | |
#define selfref(type, r, member) \ | |
((type *) r + (r->member)) | |
typedef struct { | |
int i; | |
unsigned long i_ptr; | |
} T; | |
typedef struct { | |
int i; | |
int* i_ptr; | |
} T2; | |
T *new_T(void) | |
{ | |
T *n = malloc(sizeof(T)); | |
assert(n); | |
n->i = 0; | |
n->i_ptr = offset_of(T, i); | |
*selfref(int, n, i_ptr) = (int) n->i; | |
return n; | |
} | |
int main(int argc, char **argv) | |
{ | |
// allocate or structs | |
T *a = new_T(), *b = new_T(); | |
// do stuff on on a | |
a->i = 42; | |
// move a -> b | |
memcpy(b, a, sizeof(*b)); | |
free(a); | |
// b is safe, as on as we know how to dereference it | |
assert(b->i == 42); | |
assert(*selfref(int, b, i_ptr) == 42); // we need some sort of magic | |
// to dereference it, but is | |
// possible at compile time! | |
// The traditional way | |
T2 *c = malloc(sizeof(T2)), *d = malloc(sizeof(T2)); | |
assert(c); | |
assert(d); | |
// init it by hand | |
c->i = 0; | |
c->i_ptr = &c->i; | |
// do stuff on c | |
c->i = 42; | |
// move c -> d, c is freed | |
memcpy(d, c, sizeof(*d)); | |
free(c); | |
// This is okay since int is move safe, we just copy it | |
assert(d->i == 42); | |
assert(*(d->i_ptr) == 42); // this will fail becase i_ptr points | |
// to invalid memory | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment