This behavior of CString
seems not officially supported by Microsoft (it relies on implementation details of CString
, which seem crafted to work in cases like the one you cited, but may change in the future).
Note that MSDN documentation of CString
PCXSTR
cast operator reads:
// If the prototype isn't known or is a va_arg prototype,
// you must invoke the cast operator explicitly. For example,
// the va_arg part of a call to swprintf_s() needs the cast:
swprintf_s(sz, 1024, L"I think that %s!\n", (PCWSTR)strSports);
Actually that cast is bad, since it's a C-style cast. I'd use C++-style cast static_cast<PCWSTR>(string)
or just the CString::GetString()
method instead.
Another MSDN documentation page reads (emphasis mine):
Using CString Objects in Variable Argument Functions
Some C functions take a variable number of arguments. A notable
example is printf_s
. Because of the way this kind of function is
declared, the compiler cannot be sure the type of the arguments and
cannot determine which conversion operation to perform on each
argument. Therefore, you must use an explicit type cast when you pass
a CString
object to a function that takes a variable number of
arguments. To use a CString
object in a variable argument function,
explicitly cast the CString
to an LPCTSTR
string, as shown in the
following example.
CString kindOfFruit = _T("bananas");
int howmany = 25;
_tprintf_s(_T("You have %d %s\n"), howmany, (LPCTSTR)kindOfFruit);
Again, I do prefer C++-style static_cast<PCTSTR>
to the C-style cast used in the MSDN documentation. Or calling CString::GetString()
will do just fine.
See also this blog post: Big Brother helps you.
And another thread on StackOverflow in which this issue is discussed.
CString::GetString()
, notGetBuffer()
. Note also that C-style casts are bad: please use C++-style casts:static_cast<LPCTSTR>(ss)
. – Parsec