From 7ba8a506a215846d14d71487807f5e525e9e5c16 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sat, 7 Feb 2026 19:02:38 +0900 Subject: feat: allow calling offsetof() in compile-time expression --- include/stddef.h | 2 +- src/parse.c | 4 ++++ tests/stddef.c | 23 +++++++++++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 tests/stddef.c diff --git a/include/stddef.h b/include/stddef.h index ffcf225..2689311 100644 --- a/include/stddef.h +++ b/include/stddef.h @@ -7,7 +7,7 @@ typedef unsigned long size_t; typedef int wchar_t; typedef long ptrdiff_t; -#define offsetof(T, m) (ptrdiff_t)((void*)((T*)0)->m) +#define offsetof(T, m) ((ptrdiff_t)(void*)(&((T*)0)->m)) // TODO: // - max_align_t (C11) diff --git a/src/parse.c b/src/parse.c index 55cac2b..3f55a51 100644 --- a/src/parse.c +++ b/src/parse.c @@ -2733,6 +2733,10 @@ static int eval(AstNode* e) { } } else if (e->kind == AstNodeKind_cast_expr) { return eval(e->as.cast_expr->operand); + } else if (e->kind == AstNodeKind_deref_expr) { + return eval(e->as.deref_expr->operand); + } else if (e->kind == AstNodeKind_ref_expr) { + return eval(e->as.ref_expr->operand); } else { unimplemented(); } diff --git a/tests/stddef.c b/tests/stddef.c new file mode 100644 index 0000000..f63e57c --- /dev/null +++ b/tests/stddef.c @@ -0,0 +1,23 @@ +#include +#include + +struct S { + int x; + int y; +}; +struct T { + char a; + int b; + char c; +}; + +int main() { + ASSERT_EQ(0, offsetof(struct S, x)); + ASSERT_EQ(4, offsetof(struct S, y)); + ASSERT_EQ(0, offsetof(struct T, a)); + ASSERT_EQ(4, offsetof(struct T, b)); + ASSERT_EQ(8, offsetof(struct T, c)); + + char buf[offsetof(struct T, b)]; + ASSERT_EQ(4, sizeof(buf)); +} -- cgit v1.3-1-g0d28