Skip to content

Instantly share code, notes, and snippets.

@FedeDP
Last active July 17, 2018 12:16
Show Gist options
  • Save FedeDP/823eb5e247ba6ece6ca740720a2b9810 to your computer and use it in GitHub Desktop.
Save FedeDP/823eb5e247ba6ece6ca740720a2b9810 to your computer and use it in GitHub Desktop.
Using these set of macros (GetPtr and GetSinglePtr) it is possible to refactor your struct and still having the correct types for pointers. Eg: it may happen that a uint32_t field is changed to uint8_t, but in some places it is still referred as uint32_t *tmp = myStruct->x, causing troubles.
#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#define MyPtrTypeOf(TYPE, MEMBER) typeof(&((TYPE *)0)->MEMBER)
#define GetPtr(t, i, MEMBER) \
MyPtrTypeOf(typeof(*t), MEMBER) MEMBER = \
(MyPtrTypeOf(typeof(*t), MEMBER)) ((void *)(t + i) + offsetof(typeof(*t), MEMBER))
#define GetSinglePtr(t, MEMBER) GetPtr(&t, 0, MEMBER)
typedef struct {
uint8_t x;
double y;
char *name;
} myS;
int main(void) {
myS s[10] = { 0 };
myS t = { 0, 5.245, NULL };
s[5].x = 12;
s[7].name = strdup("Hello");
/* Test Int */
GetPtr(s, 5, x);
printf("%d\n", *x);
*x = 13;
printf("%d\n", *x);
/* Test Char* */
GetPtr(s, 7, name);
printf("%s\n", *name);
free(*name);
*name = strdup("World");
printf("%s\n", *name);
free(*name);
GetSinglePtr(t, y);
printf("%.3lf\n", *y);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment