That code was written before inline functions were supported by compilers; now that they are even part of the language standard, turn macros into inline functions so that there is no need to document in comments that they will evaluate their arguments multiple times.
(one may consider switching their names to lowercase now that these are no longer macros.) Index: regex2.h =================================================================== RCS file: /OpenBSD/src/lib/libc/regex/regex2.h,v retrieving revision 1.10 diff -u -p -r1.10 regex2.h --- regex2.h 31 Dec 2020 17:20:19 -0000 1.10 +++ regex2.h 2 Jan 2021 15:59:51 -0000 @@ -107,10 +107,24 @@ typedef struct { uch mask; /* bit within array */ uch hash; /* hash code */ } cset; -/* note that CHadd and CHsub are unsafe, and CHIN doesn't yield 0/1 */ -#define CHadd(cs, c) ((cs)->ptr[(uch)(c)] |= (cs)->mask, (cs)->hash += (c)) -#define CHsub(cs, c) ((cs)->ptr[(uch)(c)] &= ~(cs)->mask, (cs)->hash -= (c)) -#define CHIN(cs, c) ((cs)->ptr[(uch)(c)] & (cs)->mask) + +static inline void +CHadd(cset *cs, char c) +{ + cs->ptr[(uch)c] |= cs->mask; + cs->hash += c; +} +static inline void +CHsub(cset *cs, char c) +{ + cs->ptr[(uch)c] &= ~cs->mask; + cs->hash -= c; +} +static inline uch +CHIN(const cset *cs, char c) +{ + return cs->ptr[(uch)c] & cs->mask; +} /* * main compiled-expression structure