I am going through a previously written code and I found StringCbPrintf() function
I found declaration on msdn site like this :
HRESULT StringCbPrintf(
_Out_ LPTSTR pszDest,
_In_ size_t cbDest,
_In_ LPCTSTR pszFormat,
_In_ ...
);
What is _in_ and _out_ here ?
And why is it needed when we already have sprintf() ?
_In_and_Out_(note: neither_in_/_out_ as you wrote, nor__In__/__Out__with double underscores, as written in some other answer) are so called SAL Annotations. They can be used with/analyzecompiler option, and can help identify bugs and problems like buffer overruns etc. with raw C buffers and pointers. In addition to MSDN documentation on SAL, you can read also this blog post.Someone ironically (and wrongly) wrote that:
missing the fact that SAL is more powerful than that. In fact, with SAL you can also specify the maximum size of a destination buffer, indicating which parameter contains the destination buffer size; e.g. if you open
<strsafe.h>header, you can read that the actual SAL annotations used forStringCbPrintfW(the Unicode version ofStringCbPrintf) is something like that:Note how the
__out_bcount(cbDest)SAL annotation applied to thepszDestparameter specifies that this is a pointer to an output buffer (__out), which size is expressed in bytes (_bcount) by the parametercbDest. As you can see, this is a rich annotation (richer than simple “const” or “nonconst“).In my opinion, SAL is kind of useless if you write C++ code with robust container classes like
std::vectororstd::string, which know their own size, etc. But SAL can be useful in C-ish code with raw pointers (like several Win32 APIs).About the second part of your question:
the main reason is that
sprintfis an unsafe and buffer overruns-prone function; instead withStringCbPrintfyou must specify the maximum size of the destination buffer, and this can help preventing buffer overruns (which are security enemies).