I'm coding up a new (personal hobby) app for Windows in c++.
In previous low-level Windows stuff I've used _TCHAR
(or just TCHAR) arrays/basic_strings for string manipulation.
Is there any advantage to using _TCHAR
over straight up Unicode with wchar_t
, if I don't care about Windows platforms pre Win2k?
edit: after submitting I discovered a similar question here from Oct 2008:
Is TCHAR still relevant?
Seems to be more consensus now about ditching TCHAR
The wchar_t type is an implementation-defined wide character type. In the Microsoft compiler, it represents a 16-bit wide character used to store Unicode encoded as UTF-16LE, the native character type on Windows operating systems.
Remarks. For Unicode platforms, TCHAR is defined as synonymous with the WCHAR type. MAPI clients can use the TCHAR data type to represent a string of either the WCHAR or char type. Be sure to define the symbolic constant UNICODE and limit the platform when it is required.
WCHAR (or wchar_t on Visual C++ compiler) is used for Unicode UTF-16 strings. This is the "native" string encoding used by Win32 APIs. CHAR (or char ) can be used for several other string formats: ANSI, MBCS, UTF-8.
a PWSTR would be a wchar_t string pointer. That is a UNICODE (usually UCS2) string with each character taking 16 bits. a char* would be a pointer 8 bits per character. this could be ASCII, ANSI, UTF8, or one of many hundreds of other encodings.
No there is not. Just go with wchar_t.
TCHAR is only useful if you want to be able to use a conditional compilation switch to convert your program to operate in ASCII mode. Since Win2K and up are unicode platforms this switch does not provide any value. You'd instead be implying to other developers in your project that ASCII was a valid target when in fact it's not.
wchar_t
is a c++ defined type, that is 16 bits in Visual Studio, but is 32bits in various gcc compilers. Its always capable of holding a unicode codepoint.
TCHAR
and _TCHAR
are not "unicode" characters - theyre meant to be used in code that may be compiled and/or used in Unicode OR Ansi programs:
_TCHAR
is - from its leading underscore - a Microsoft C runtime library "extension" to the c++ standard. _TCHAR
will, when _UNICODE
is defined, be a 16bit character, when _MBCS
is defined, be a multibyte character, and when neither is defined, be a singlebyte character. Use this type if you use MS CRT defined string functions that are prefixed with _t
: _tcscpy()
for example is the replacement for strcpy()
/wcscpy()
.
TCHAR
is a defined by the Win32 API. This type is a CHAR
when UNICODE
is not defined, and a WCHAR
when UNICODE
is defined (note the lack of an underscore on this type). Windows API functions that take strings likewise expect WCHAR
strings in UNICODE
builds and CHAR
strings in non unicode builds.
To summarize:
wchar_t
is a cross platform c++ defined type that can hold a unicode code point - on compilers other than Microsoft, is frequently 32bits wide._TCHAR
is a microsoft defined type that is paired with _tcs*
c runtime functions that changes its type based on the definition of _UNICODE
and/or _MBCS
.TCHAR
is a Windows API defined type that changes its type based on the definition (or not) of UNICODE
.WCHAR
is the native Windows API type for dealing with unicode strings. When using a GCC toolset to build windows code, this will be 16bits wide where wchar_t
might not.Does that help? I don't know.
I'd go with plain wchar_t
The advantage to TCHAR
is that it allows you to toggle Unicode on and off and your code accessing the Windows API will keep working.
The problem with it is that no other API will accept it.
std::cout
will choke on a std::wstring,
std::string will choke on being initialized with a wchar_t*
and so on.
From the point of view of every other library, you should use either char
or wchar_t
, and switching between them is nontrivial.
And since non-Unicode compatibility was only really an issue in Windows 95, there's really no point in supporting both any more. Enable Unicode, use wchar_t
and save yourself the headaches.
OF course, to avoid confusion then, you might also want to call the *W versions of Win32 functions. Instead of CreateWindow, CreateWindowW, for example, so that even if someone compiles your code with Unicode disabled in the project settings, the code will still work. If you're going to hardcode for Unicode support, you might as well do so consistently.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With