Several function-like macros expand a runtime argument into two or more evaluating
positions, so an argument with side effects is evaluated more than once
(e.g. IntToStr(*p++)).
Examples:
IntToStr_1(value) -> int_to_str((value), IntAllocator((value))) — value twice.
StrInitFromZstr_1(zstr) -> ... ((zstr), ZstrLen(zstr)) — zstr twice.
Str{PushBack,PushFront,Insert}Many _Generic forms — source used as the pointer
and again inside ZstrLen(...).
Fix direction: route the reused derivation through single-eval functions
(cross-compiler, no statement-expressions), keeping behaviour and tests unchanged.
Several function-like macros expand a runtime argument into two or more evaluating
positions, so an argument with side effects is evaluated more than once
(e.g.
IntToStr(*p++)).Examples:
IntToStr_1(value)->int_to_str((value), IntAllocator((value)))—valuetwice.StrInitFromZstr_1(zstr)->... ((zstr), ZstrLen(zstr))—zstrtwice.Str{PushBack,PushFront,Insert}Many_Generic forms — source used as the pointerand again inside
ZstrLen(...).Fix direction: route the reused derivation through single-eval functions
(cross-compiler, no statement-expressions), keeping behaviour and tests unchanged.