A parameter of function requires an LPCTSTR
type variable; what if we pass a CString
type variable? Is it safe or is there anything that we should look at in this case?
CodePudding user response:
Is it safe or is there anything that we should look at in this case?
Generally (see note, below), yes, it is safe. The CString
class has an operator LPCTSTR()
, which returns the content of the string as a C-style, nul-terminated char
or wchar_t
array (well, a pointer to its first element), depending on the current compiler setting of the "Character Set" option (i.e. whether or not UNICODE
and/or _UNICODE
is/are defined). Thus, the returned type will (or should) match the required const char*
vs const wchar_t*
pointer type for your function parameter. (Note that this is not safe to use for function parameters that are not const
qualified).
In "olden days", there were some compilers that I used that would complain about the 'implicit' conversion when doing just this, so I used the CString::GetString()
function, instead. However, these do exactly the same thing. From the "atlsimpstr.h" header:
template< typename BaseType , bool t_bMFCDLL = false>
class CSimpleStringT
{
//...
operator PCXSTR() const throw()
{
return( m_pszData );
}
//...
PCXSTR GetString() const throw()
{
return( m_pszData );
}
//...
Important Note: One case where using this "implicit conversion" is not safe is for functions that take variadic arguments, like printf
or the .Format()
member of CString
itself; in such cases, the compiler will (rightly) complain of non-portable conversions. Take the following code:
#include <afx.h>
int main()
{
CString param = _T("param");
CString text;
text.Format(_T("Param is %s"), param);
return 0;
}
The clang-cl compiler gives this error:
error : cannot pass object of non-trivial type 'CString' (aka 'CStringT<wchar_t, StrTraitMFC_DLL<wchar_t>>') through variadic method; call will abort at runtime [-Wnon-pod-varargs]
And even MSVC itself gives:
warning C4840: non-portable use of class 'ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>' as an argument to a variadic function
In such a case, you can either use the .GetString()
function mentioned earlier, or make the conversion explicit:
text.Format(_T("Param is %s"), param.operator LPCTSTR());
CodePudding user response:
CString contains an implicit conversion operator for LPCTSTR. It was designed for this exact usage.
It's the fact that you're passing a const string that can't be modified that makes it safe.