-
Notifications
You must be signed in to change notification settings - Fork 967
Updates to documentation for string printf functions #3328
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…nt is zero, len is returned as the count of characters required to format the output (not including the terminating null). * Clarify that [v]snprintf() will not attempt to truncate a zero-character formatted data string when count = 0, by placing a null-terminator at buffer[-1]. * Clarify that for functions other than [v]snprintf(), if len > count and buffer is a null pointer, then either len will be returned - without error - if count is zero, or the invalid parameter handler will be invoked if count is nonzero.
…mily of functions.
…nwprintf_s()/_vsnwprintf_s().
…tion has occurred.
@adr26 : Thanks for your contribution! The author(s) have been notified to review your proposed change. |
I have incorrectly conflated the documentation on encoding errors (for wide string function variants) with the errors that can occur during formatting. From the C specification:
I will add a new test case for this to my test code, update the documentation accordingly and re-open the PR. Sorry for the confusion. Thanks, Andrew R |
I added test cases to my test code to examine the behaviour of the various families of In all cases, I have updated the PR description, plus updated the documentation accordingly — having also rebased to the latest code from the main Please let me know if you've any questions on what I've done. Thanks, Andrew R |
Ah, alas — GitHub won't let me re-open this PR! I will set up a new one... |
I can't reopen it either. I'll watch for your new one. |
Thanks @tycastMSFT — I've opened a new PR: #3411, where I've rolled in my corrected descriptions of the handling of encoding errors. I realise that it'll need dev review, and there may be a discussion of to what extent you want to codify the current encoding-error-handling behaviour, but hopefully my changes to the docs are an accurate description of the current CRT behaviour and will serve as a useful basis for discussing how the docs should be updated (and may perhaps even be able to be accepted wholesale!) Andrew R |
@TylerMSFT Do you not see a "Reopen and comment" button at the bottom of a comment box like this one? There may be other ways to reopen a PR, but this one is how I usually do it. If you don't, then maybe I didn't set up your admin privileges correctly. |
@corob-msft - I see the button but it won't respond, i.e. it's not clickable. |
Hi @corob-msft, @TylerMSFT, Please ignore #3328 (I think github refuses to allow you to re-open a PR if you force-pushed, which I did to my repo once I'd rebased my changes with up-to-date changes from the MicrosoftDocs repo). Instead, please look at my new PR: #3411, where I've rolled in my corrected descriptions of the handling of encoding errors. I realise that the PR will need dev review, and there may be a discussion of to what extent you want to codify the current encoding-error-handling behaviour, but hopefully my changes to the docs in #3411 are an accurate description of the current CRT behaviour and will serve as a useful basis for discussing how the docs should be updated (and may perhaps even be able to be accepted wholesale!) Andrew R |
@adr26 Don't worry, we'll work with your latest PR. We're just curious why one of our buttons doesn't work as expected. There's hover text associated with the button: "There is already an open pull request from adr26:master to MicrosoftDocs:master". It may be that you can only have one open PR from a particular branch at a time? I bet that's it. |
The behaviour of
vsnprintf()
withcount == 0
andbuffer != NULL
is to return the length of the formatted data, rather than returning-1
— as the documentation currently states. I have cross-referenced the behaviour ofvsnprintf()
with the C specification, and confirmed that the implementation behaviour (returning the length of the formatted data) conforms to the C specification and is correct. Therefore, the currentvsnprintf()
documentation is incorrect and needs to be updated.After making this observation, I conducted a broader review of the documentation for the
*sn[w]printf*
family of functions, making these updates as a result.In general, I've corrected a number of errors in the description of the behaviour of the
*sn[w]printf*
family of functions, and have aligned the information for:_snprintf_s()
/_snwprintf_s()
and_vsnprintf_s()
/_vsnwprintf_s()
snprintf()
/_snprintf()
/_snwprintf()
andvsnprintf()
/_vsnprintf()
/_vsnwprintf()
A detailed description of the problems addressed on each page is given below:
_snprintf_s()
/_snwprintf_s()
:Add description of behaviour which occurs when an encoding error occurs during formatting — setting
errno
toEILSEQ
in all cases and either returning a negative value for a string conversion specifier, or skipping the character for a character conversion specifier.Clarify that in cases where truncation does not occur, null-termination is performed
Clarify truncation behaviour:
count < sizeOfBuffer
, but formatted data> count
, then formatted data is truncated tocount
characters, null-terminated and -1 is returned with no error handler / update toerrno
count == _TRUNCATE
, and formatted data>= sizeOfBuffer
, then formatted data is truncated to(sizeOfBuffer - 1)
characters, null-terminated and -1 is returned with no error handler / update toerrno
count >= sizeOfBuffer
, formatted data>= sizeOfBuffer
, andcount != _TRUNCATE
, the invalid parameter handler is invoked. If continued, the functions truncate the buffer to an empty string, return -1 and seterrno
toERANGE
Clarify error handling behaviour:
buffer
isNULL
, anEINVAL
error occurs if (and only if) eithercount
orsizeOfBuffer
are!= 0
(if both are 0, no error occurs and 0 is returned)EINVAL
error does not occur in all cases wherecount == 0
, only when one of the other conditions are met (count
cannot be negative, assize_t
is unsigned)sizeOfBuffer
(notcount
!)== 0
, and additionally if buffer is notNULL
, then anEINVAL
error occursAdd copy of error conditions table from
_vsnprintf_s()
/_vsnwprintf_s()
.snprintf()
/_snprintf()
/_snwprintf()
:Add description of behaviour which occurs when an encoding error occurs during formatting — setting
errno
toEILSEQ
in all cases and either returning a negative value for a string conversion specifier, or skipping the character for a character conversion specifier.Clarify truncation behaviour:
snprintf()
, clarify that null-termination by writing tobuffer[count-1]
is only performed ifcount != 0
._snprintf()
/_snwprintf()
, clarify that non-terminated truncation is performed only whenbuffer != NULL
(ifbuffer == NULL
andcount != 0
, it is an error and if ifbuffer == NULL
andcount == 0
, the length of the formatted data is returned)._vsnprintf_s()
/_vsnwprintf_s()
:Add description of behaviour which occurs when an encoding error occurs during formatting — setting
errno
toEILSEQ
in all cases and either returning a negative value for a string conversion specifier, or skipping the character for a character conversion specifier.Clarify that in cases where truncation does not occur, null-termination is performed
Clarify truncation behaviour:
count >= sizeOfBuffer
and formatted data>= sizeOfBuffer
, then only if alsocount != _TRUNCATE
the invalid parameter handler is invoked, etc.Clarify error handling behaviour:
buffer
isNULL
, anEINVAL
error occurs if (and only if) eithercount
orsizeOfBuffer
are!= 0
(if both are 0, no error occurs and 0 is returned)EINVAL
error does not occur in all cases wherecount == 0
, only when one of the other conditions are met (count
cannot be negative, assize_t
is unsigned)sizeOfBuffer
(notcount
!)== 0
, and additionally if buffer is notNULL
, then anEINVAL
error occursUpdate error conditions table to correct from
count == 0
tosizeOfBuffer == 0
as the condition required for anEINVAL
error (whenbuffer != NULL
).vsnprintf()
/_vsnprintf()
/_vsnwprintf()
:Add description of behaviour which occurs when an encoding error occurs during formatting — setting
errno
toEILSEQ
in all cases and either returning a negative value for a string conversion specifier, or skipping the character for a character conversion specifier.Clarify that in cases where truncation does not occur, null-termination is performed
Clarify truncation behaviour:
vsnprintf()
, clarify that null-termination by writing tobuffer[count-1]
is only performed ifcount != 0
._vsnprintf()
/_vsnwprintf()
, clarify that non-terminated truncation is performed only whenbuffer != NULL
(ifbuffer == NULL
andcount != 0
, it is an error and if ifbuffer == NULL
andcount == 0
, the length of the formatted data is returned).vsnprintf()
, clarify that ifcount == 0
andbuffer != NULL
, the length of the formatted data is returned, rather than-1
(as is the case for_vsnprintf()
/_vsnwprintf()
).To verify the behaviour of these functions, I constructed the attached test code (printf.zip). The updated descriptions of these functions' behaviour can be verified using the output from this: