Home > Back-end >  Is it safe to replace LPCTSTR with CString?
Is it safe to replace LPCTSTR with CString?

Time:05-02

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.

  • Related