The signed and unsigned fixed-width integers (int32_t, uint32_t etc.) are optional
in C99 (and above). Use the non-optional minimum-width integers (int_fast32_t, uint_fast32_t and int_least32_t, uint_least32_t etc.) instead.
To simulate unsigned wrap-around, use the GUF_UWRAP macros in guf_common.h
cf. https://en.cppreference.com/w/c/types/integer (last-retrieved: 2025-05-18)
An assertion GUF_ASSERT(str_is_valid(dst)) failed in guf_str_copy when it called guf_str_cstr(dst)
since guf_str_cstr assumes an already valid string, which was not the case when src was a short string.
Therefore, we get the dst's c_str now without calling guf_str_cstr(dst)
(Found by writing DbufStrTest.)
Expressions like
(uin16_t)a * (uint16_t)b * (uint16_t)c
might be promoted to (signed) int (in that example, on platforms where sizeof(int) > sizeof(uint16_t)),
and therefore lead to undefined behaviour on overflow.
The above expression can be fixed as
1u * (uint16_t)a * (uint16_t)b * (uint16_t)c
(The 1u makes sure a, b, and c would be promoted to unsigned int (instead of int) on platforms where sizeof(int) > sizeof(uint16_t))
cf. https://stackoverflow.com/questions/27001604/32-bit-unsigned-multiply-on-64-bit-causing-undefined-behavior
Still not sure whether it's better to calculate
rref[pivot_row][col] * (rref[row][pivot_col] / pivot_val) (option 1)
vs.
rref[pivot_row][col] * rref[row][pivot_col] / pivot_val (option 2)
(i.e. a * b / c vs. "a * (b/c))
in terms of floating point error.
But I think option 1 (current commit) is better, since the scale factor
(rref[row][pivot_col] / pivot_val) is always <= 1 here (I think).