Quick question for those who've tried it — does this play with existing C
codebases incrementally, or is it more of a "new project only" situation?
The README didn't make that obvious to me.
It's designed to be incremental. For example, you can do a search for `sprintf` and replace it with `ssprintf`. The function signature is the same. Any instance of printing to a character array just works. Think of the APIs as "the stuff you usually do by hand, but safer".
If you get compiler errors, it means you were printing to a heap-allocated buffer (or a buffer whose bounds you did not know), and you should be propagating bounds and using `snprintf`.
Integer conversion is the same way. If you have something like
int v1;
uint64_t v2;
<stuff happens>
v2 = (uint64_t)v1;
Then you can replace it with
v2 = __cast_signed_unsigned(uint64_t, v1);
and you'll get a runtime trap when v1 is a negative value, meaning you can both enable -Wint-conversion and have defined behavior for when the value in a certain integer type is not representable in another.
It's designed to be incremental. For example, you can do a search for `sprintf` and replace it with `ssprintf`. The function signature is the same. Any instance of printing to a character array just works. Think of the APIs as "the stuff you usually do by hand, but safer".
If you get compiler errors, it means you were printing to a heap-allocated buffer (or a buffer whose bounds you did not know), and you should be propagating bounds and using `snprintf`.
Integer conversion is the same way. If you have something like
int v1; uint64_t v2;
<stuff happens>
v2 = (uint64_t)v1;
Then you can replace it with
v2 = __cast_signed_unsigned(uint64_t, v1);
and you'll get a runtime trap when v1 is a negative value, meaning you can both enable -Wint-conversion and have defined behavior for when the value in a certain integer type is not representable in another.