Re: [PATCH 01/10] ivec: introduce the C side of ivec
- From
René Scharfe <l.s.r@web.de>
- Date
- Jan 18, 2026, 14:58 UTC
- Message-ID
- <f5b36fd0-1942-499c-bf4a-1107a3afd951@web.de>
- In-Reply-To
- <CAH=ZcbCuY22WCqzyK-=Adw924a6ZJqnMYjWK9fxwoFn5xK9q-w@mail.gmail.com>
On 1/17/26 5:04 PM, Ezekiel Newren wrote:
Show 24 quoted lines
>
> I don't like this solution. ivec_push() is the only function that
> deals with actual values. The rest are just generic memory management
> functions. What if we used:
>
> #define ivec_init(vec) { \
> (vec)->ptr = NULL; \
> (vec)->length = 0; \
> (vec)->capacity = 0; \
> (vec)->element_size = sizeof(*(vec)->ptr); \
> }
>
> #define ivec_push_unsafe(vec, value) (vec)->ptr[(vec)->length++] = (value)
>
> /*
> * grow by at least 1
> */
> #define ivec_push(vec, value) { \
> if ((vec)->length == (vec)->capacity) \
> ivec_reserve(vec, 1); \
> ivec_push_unsafe(vec, value); \
> }
>
> Instead of concrete functions?These macros are OK on the C side in respect to type-safety.
I guess they would have to be duplicated somehow in Rust?
How would ivec_reserve() look like?
The macros use their parameter "vec" multiple times, though, so callers must not pass in an expression with a side-effect, as it would be evaluated more than once. We have a few of those already. You have to be careful not to do stuff like this (example of calling a _push-like function with an argument with a side-effect from strbuf.c::strbuf_join_argv()):
while (--argc) strbuf_addstr(buf, *(++argv));
Also they can't be used like a function -- you'd have to call them without a trailing semicolon. That's a small issue and easily overcome by wrapping their body in "do { } while (0)".
René