The ambiguity begins with the C standard itself. Both C99 and C11 have the same snprintf function description. Here is a description with C99:
7.19.6.5 snprintf function
abstract
1 #include <stdio.h> int snprintf(char * restrict s, size_t n, const char * restrict format,...);
Description
2 The function snprintf equivalent to fprintf , except that the output is written to the array (specified by the s argument), and not to the stream. If n is zero, nothing is written, and s may be a null pointer. Otherwise, output characters outside of n-1 st are discarded, not written to the array, and the null character is written at the end of the characters actually written to the array. If copying occurs between overlapping objects, the behavior is undefined.
Returns
3 The snprintf function returns the number of characters that were written if n were large enough, not counting the terminating null character or a negative value if an encoding error occurred. Thus, null-terminated output was completely written if and only if the return value is non-negative and less than n .
On the one hand, the proposal
Otherwise, the output characters outside the n-1 1st are discarded, not written to the array, and the null character is written at the end of the characters actually written to the array
Says that
if ( s points to an array of 3 characters long and) n is 3, then 2 characters will be written, and characters outside the second will be discarded ; then the null character is written after these 2 (and the null character will be written in the third character).
And this, in my opinion, answers the original question.
ANSWER:
If copying occurs between overlapping objects, the behavior is undefined.
If n is 0, then nothing is written to the output
otherwise, if encoding errors are not encountered, the ALWAYS output terminates to zero (regardless of whether the output matches the output array or not, and if not, some characters are discarded, so the output array never overflows)
otherwise (if encoding errors are encountered), the output may remain non-zero.
On the other hand
The last sentence
Thus, null-terminated output was completely written if and only if the return value is non-negative and less than n
gives ambiguity (or my English is not good enough). I can interpret this sentence in at least two ways:
1. An output is completed with a zero value if and only if the return value is non-negative and less than n (this means that if the return value is not less than n , that is, the output (including the terminating null character) does not fit into the array, then the output does not end with zero )
2. The output is completed (not a single character has been discarded) if and only if the return value is non-negative and less than n .
I believe that interpretation 1 above contradicts the ANSWER, causes misunderstanding and lengthy discussions. This is why the last sentence describing the snprintf function needs to be changed to eliminate any ambiguity (which gives grounds for writing a sentence in the C language standard).
An example of an explicit statement, I believe, can be taken from http://en.cppreference.com/w/c/io/fprintf (see 4) ), thanks to @ "Martin Ba" for the link.
See also the question " snprintf: Are there any standard C suggestions / plans to change the description of this function? ".