-
Notifications
You must be signed in to change notification settings - Fork 966
Updates to documentation for string printf functions #3411
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
* Fix description of behaviour when encoding errors occur. * Clarify truncation behaviour (matching vsnprintf_s family of functions). * Add error condition table (matching vsnprintf_s family of functions).
* Fix description of behaviour when encoding errors occur. * Clarify truncation behaviour of vsnprintf_s family of functions. * Clarify error condition table for vsnprintf_s family of functions.
* Clarify the return value behaviour of snprintf family of functions. * Clarify truncation behaviour of snprintf family of functions.
…th snprintf family of functions: * Fix description of behaviour when encoding errors occur. * Clarify the return value behaviour of vsnprintf family of functions. * Clarify truncation behaviour of vsnprintf family of functions.
@adr26 : Thanks for your contribution! The author(s) have been notified to review your proposed change. |
#label:"aq-pr-triaged" |
Thank you very much, @adr26. I am referring this to the dev who works in this area for review. They are preparing for a conference right now so there may be some delay before he can look at it. |
@TylerMSFT - thanks for the update: I put this together on the back of some work I'd done for a codebase my team owns, which ships internally with sources, and where the codebase still has to support some clients who compile it with VS2008(!) and VS2013. C99-conformant We implemented wrappers for the Having done that, I wanted to make sure that what I'd learned about the differences between the behaviour I'd observed in my characterisation and what was in the docs was preserved for posterity: mostly for my sanity, in case I ever have to look at that code again, but also for the benefit of the wider community. As such, I hope this contribution is helpful, but it isn't very high-priority. I hope your dev's preparations go well, and I'll be glad to discuss further once they've got time to look at it: thank you again! Andrew R |
@adr26, you probably thought this was lost and forgotten. But no-I finally had time to go through it in detail. I'm going to close this, but nothing is lost. I took all this material and converted it to a table in this PR I thought a table would be a faster way for people to process the info that otherwise takes paragraphs to explain. You are welcome to review that PR because this space provides plenty of opportunity for errors. I tested the claims in the new tables against VS 2022. |
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: