> then why not just use memmove() instead of strncpy() if no-NUL is the goal?
no-nul is not the goal of strncpy, it's the effect of strncpy.
strncpy is designed to work on fixed-size, nul-padded strings. That's why it fills the destination buffer with nuls if the source is too short, and it doesn't guarantee nul-termination (if the source is exactly the size of the destination).