aboutsummaryrefslogtreecommitdiffhomepage
path: root/mem.c
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2025-12-15 22:39:52 +0100
committerlemon <lsof@mailbox.org>2025-12-15 22:39:52 +0100
commit302e24671942051d70707586cf8c605a5815edac (patch)
tree51e25fb6cd7e828c82ce5f17ffc775117121acee /mem.c
parentc6c0f2ef35175075e91169113cfe856f29b3eb9a (diff)
create distinct interned string type
Interned strings are used pervasively, so it's a good idea to add a layer of type safety to differentiate them from general cstrs and avoid potential bugs from comparing non-interned and interned strings. Not that that's happened so far that I can remember, but it could. I'm 90% sure it's legal to alias `struct {char c;}` pointers with `char` pointers. This specific typedef gives type safety but with a simple one-way `internstr -> const char *` typecast (with `&istr->c`). Converting the other way around is more intentional: a straight up cast `(internstr)cstr` which sticks out as unchecked and probably wrong, or calling the intern(cstr) function, which is the right way.
Diffstat (limited to 'mem.c')
-rw-r--r--mem.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/mem.c b/mem.c
index 6866216..eefe96a 100644
--- a/mem.c
+++ b/mem.c
@@ -37,12 +37,12 @@ void *
}
/** string interning **/
-const char *
+internstr
intern(const char *s)
{
static uint N, n;
static struct ht {
- const char *s;
+ internstr s;
size_t h;
} *ht;
static struct { char m[sizeof(struct arena) + (2<<10)]; struct arena *_a; } amem;
@@ -75,7 +75,7 @@ intern(const char *s)
N = nnew;
i = h;
continue;
- } else if (h == ht[i].h && !strcmp(s, ht[i].s)) {
+ } else if (h == ht[i].h && !strcmp(s, &ht[i].s->c)) {
return ht[i].s;
}
++i;