* +1 to sanitizers.
* +1 to clangd and bear.
* +1 to namespacing.
* Make sure you have a code formatter. I use clang-format, but any should work.
* Do not use recent C features unless you need them. VLA's in particular are a bad choice. An example of something you might need is `alignof()` and `max_align_t`, which are basically necessary if writing your own allocator(s).
* Write destructors for your types. If they own data, their destructor should free that data. This has helped me avoid countless memory leaks.
* Finally (and this will probably be controversial), use unsigned arithmetic as much as you can! The reason for this is because unsigned arithmetic has far fewer cases of UB, and with a little work, you can simulate two's-complement signed arithmetic in C without UB.
Source: I am a C programmer with a public project that has had very few memory bugs or UB bugs found in releases. In particular, unsigned arithmetic is what got me farther than most, since most will use Valgrind/sanitizers.