Consider the following example:
int r, n = -1;
r = snprintf (NULL, 0, "foo%n", &n);
printf ("%d %d\n", r, n);
With glibc 2.24, I get 3 3 instead of the expected 3 0. Indeed, the glibc manual (whose description seems equivalent to ISO C11) says for %n:
12.12.6 Other Output Conversions
The '%n' conversion is unlike any of the other output conversions.
It uses an argument which must be a pointer to an 'int', but instead of
printing anything it stores the number of characters printed so far by
this call at that location.
but due to the size 0, nothing has been printed. Thus one should have n = 0.
Note that in its snprintf description:
The return value is the number of characters which would be
generated for the given input, excluding the trailing null.
"would be", thus the expected r = 3. There is no such "would be" for %n. In the C11 draft I have, this is said in a similar way:
The snprintf function returns the number of characters that would
have been written had n been sufficiently large, [...]
The "had n been sufficiently large" is quite explicit. But again, there is no such thing for %n.
The description only talks about the produced characters being discarded instead of written to memory. The side effects of producing the output is still performed. In case of lack of space the output stream is just the equivalent of /dev/null.
Agreed, this looks like an imprecision or a defect in the C standard.