aboutsummaryrefslogtreecommitdiff
path: root/2025-linuxdays/priv.c
diff options
context:
space:
mode:
Diffstat (limited to '2025-linuxdays/priv.c')
-rw-r--r--2025-linuxdays/priv.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/2025-linuxdays/priv.c b/2025-linuxdays/priv.c
new file mode 100644
index 0000000..ed3ad1a
--- /dev/null
+++ b/2025-linuxdays/priv.c
@@ -0,0 +1,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');
+}