Submitter:Fred J. Tydeman
Submission Date: 2020-09-02
Document: WG14 N2571
Title: N2571: snprintf
Reference Documents: N2478, N2495

Summary

One reading of snprintf has ambiguous or contradictorary statements.

"A if and only if B and C" can be parsed two ways:

• "(A if and only if B) and (C)"
• "(A) if and only if (B and C)"

I believe it would be clearer if done as:

• "A if and only if B, and C" for the first meaning.
• "A if and only if both B and C" for the second meaning.

In the returns section (paragraph 3) is an "if and only if" statement. If the second part of that is false, then the entire first part must be false. That means, if n is less than the return value [second part false], then the output is NOT complete and the output is NOT null terminated [first part false]. However, the description (paragraph 2) says that the output is null terminated for this case.

I also find paragraph 2:

Otherwise, ..., and a null character is written at the end of the characters actually written into the array.

confusing for the case where nothing is written. Is a null character written? I assume yes.

``````char buf[99];
rc = snprintf(buf, 0, "", 42);   /* rc == 0, buf is left alone */
rc = snprintf(buf, 1, "", 42);   /* rc == 0, buf is "\0" */
rc = snprintf(buf, 9, "", 42);   /* rc == 0, buf is "\0" */
rc = snprintf(buf, 0, "%i", 42); /* rc == 2, buf is left alone */
rc = snprintf(buf, 1, "%i", 42); /* rc == 2, buf is "\0" */
rc = snprintf(buf, 2, "%i", 42); /* rc  == 2, buf is "4\0" */
rc = snprintf(buf, 9, "%i", 42); /* rc ==  2, buf is "42\0" */
```
```

Most implementations do null-terminate the output for small n, but I have found at least one implementation that does not null-terminate the output when n is less than the return value.

Technical Corrigendum:

In 7.21.6.5 The snprintf function: Change in paragraph 3 (Returns):

Thus, the null-terminated output has been completely written if and only if the returned value is nonnegative and less than n.

to:

Unless either n is zero or the return code is negative, the output is null-terminated. The output has been completely written if and only if the returned value is both nonnegative and less than n.

or:

Unless either n is zero or the return code is negative, the output is null-terminated. The output has been completely written if and only if the nonnegative returned value is less than n.

The same fix needs to also be applied to

• 7.21.6.12 The vsnprintf function
• 7.22.1.3 The strfromd, strfromf, and strfroml functions
• 7.22.1.4 The strfromdN functions
• K.3.5.3.5 The snprintf_s function
• K.3.5.3.12 The vsnprintf_s function
• K.3.9.1.3 The snwprintf_s function
• K.3.9.1.8 The vsnwprintf_s function