Lately, I noticed a strange case I would like to verify:
By SUS, for %n
in a format string, the respective int
will be set to the-amount-of-bytes-written-to-the-output.
Additionally, for snprintf(dest, 3, "abcd")
, dest
will point to "ab\0"
. Why? Because no more than n (n = 3) bytes are to be written to the output (the dest
buffer).
I deduced that for the code:
int written;
char dest[3];
snprintf(dest, 3, "abcde%n", &written);
written
will be set to 2 (null termination excluded from count).
But from a test I made using GCC 4.8.1, written
was set to 5.
Was I misinterpreting the standard? Is it a bug? Is it undefined behaviour?
Edit:
@wildplasser said:
... the behavior of %n in the format string could be undefined or implementation defined ...
And
... the implementation has to simulate processing the complete format string (including the %n) ...
@par said:
written
is 5 because that's how many characters would be written at the point the%n
is encountered. This is correct behavior.snprintf
only copies up tosize
characters minus the trailing null ...
And:
Another way to look at this is that the
%n
wouldn't have even been encountered if it only processed up to 2 characters, so it's conceivable to expectwritten
to have an invalid value...
And:
... the whole string is processed via
printf()
rules, then the max-length is applied ...
Can it be verified be the standard, a standard-draft or some official source?
%n
in the format string could be undefined or implementation defined if the returnvalue is >= the 2nd argument. In any case, the implementation has to simulate processing the complete format string (including the%n
) to obtain the correct return value, so the side-effect can be obtained on the fly. – Frow