aboutsummaryrefslogtreecommitdiff
path: root/2025-linuxdays/priv.c
blob: ed3ad1a15d7761f33400d33766d1b48bd754cc23 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <stddef.h>
#include <stdio.h>

struct pub {
  void (*print_name)(struct pub *);
};
typedef struct pub *pub_t;
#define pub_print_name(PUB) (PUB)->print_name(PUB)

struct priv {
  struct pub pub;
  const char *name;
};
void pname_priv(struct pub *pub) {
  struct priv *priv = (struct priv *)pub;
  printf("%s", priv->name);
}

struct wrap {
  struct pub *subpub;
  struct pub pub;
};
void pname_wrap(struct pub *pub) {
  struct wrap *wrap = (void *)pub - offsetof(struct wrap, pub);
  printf("Wrap: ");
  wrap->subpub->print_name(wrap->subpub);
}

int main(int argc, char *argv[]) {
  struct priv priv = {.pub = {pname_priv}, .name = "FOO"};
  pub_t p = &priv.pub;
  pub_print_name(p);
  putchar('\n');

  struct wrap wrap = {.pub = {pname_wrap}, .subpub = &priv.pub};
  wrap.pub.print_name(&wrap.pub);
  putchar('\n');
}