Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Starting a new Windows app: Should I use _TCHAR or wchar_t for text?

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

like image 423
kibibu Avatar asked Aug 21 '09 13:08

kibibu


People also ask

What is the use of wchar_t?

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.

What is Tchars?

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.

What is Wchar C++?

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.

What is Pwstr?

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.


3 Answers

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.

like image 108
JaredPar Avatar answered Nov 06 '22 11:11

JaredPar


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.

like image 34
Chris Becke Avatar answered Nov 06 '22 13:11

Chris Becke


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.

like image 33
jalf Avatar answered Nov 06 '22 12:11

jalf