It's not possible to use it safely unless you know that the source string fits in the destination buffer. Every strncpy must be followed by `dst[sizeof dst - 1] = 0`, and even if you do that you still have no idea if you truncated the source string, so you have to put in a further check.
snprintf only returns negative if an "encoding error" occurs, which has to do with multi-byte characters.
I think for that to possibly happen, you have to be in a locale with some character encoding in effect and snprintf is asked to print some multi-byte sequence that is invalid for that encoding.
Thus, I suspect, if you don't call that "f...f...frob my C program" function known as setlocale, it will never happen.
> Thus, I suspect, if you don't call that "f...f...frob my C program" function known as setlocale, it will never happen.
Of all the footguns in a hosted C implementation, I believe setlocale (and locale in general) is so broken that even compilers and library developers can't workaround it to make it safe.
The only other unfixable C-standard footgun that comes close, I think, are the environment-reading-and-writing functions, but at least with those, worst-case is leaking a negligible amount of memory in normal usage, or using an old value even when a newer one is available.
I see that in Glibc, snprintf goes to the same general _IO_vsprintf function, which has various ominous -1 returns.
I don't think I see anything that looks like the detection of a conversion error, but rather other reasons. I would have to follow the code in detail to convince myself that glibc's snprintf cannot return -1 under some obscure conditions.
Defending against that value is probably wise.
As far as C locale goes, come on, the design was basically cemented in more or less its current form in 1989 ANSI C. What the hell did anyone know about internationalizing applications in 1989.