Using tchar.h data types with _MBCS
Microsoft Specific
As the table of generic-text routine mappings indicates (see Generic-text mappings), when the manifest constant _MBCS
is defined, a given generic-text routine will map to one of the following kinds of routines:
An SBCS routine that handles multibyte bytes, characters, and strings appropriately. In this case, the string arguments are expected to be of type
char*
. For example,_tprintf
maps toprintf
; the string arguments toprintf
are of typechar*
. If you use the_TCHAR
generic-text data type for your string types, the formal and actual parameter types forprintf
match because_TCHAR*
maps tochar*
.An MBCS-specific routine. In this case, the string arguments are expected to be of type
unsigned char*
. For example,_tcsrev
maps to_mbsrev
, which expects and returns a string of typeunsigned char*
. Again, if you use the_TCHAR
generic-text data type for your string types, there's a potential type conflict because_TCHAR
maps to typechar
.
Following are three solutions for preventing this type conflict (and the C compiler warnings or C++ compiler errors that would result):
Use the default behavior. TCHAR.H provides generic-text routine prototypes for routines in the run-time libraries, as in the following example.
char *_tcsrev(char *);
In the default case, the prototype for
_tcsrev
maps to_mbsrev
through a thunk in LIBC.LIB. This thunk changes the types of the_mbsrev
incoming parameters and outgoing return value from_TCHAR*
(such aschar*
) tounsigned char*
. This method ensures type matching when you're using_TCHAR
, but it's relatively slow because of the function call overhead.Use function inlining by incorporating the following preprocessor statement in your code.
#define _USE_INLINING
This method causes an inline function thunk, provided in TCHAR.H, to map the generic-text routine directly to the appropriate MBCS routine. The following code excerpt from TCHAR.H provides an example of how it's done.
__inline char *_tcsrev(char *_s1) {return (char *)_mbsrev((unsigned char *)_s1);}
If you can use inlining, it's the best solution, because it guarantees type matching and has no extra time cost.
Use "direct mapping" by incorporating the following preprocessor statement in your code.
#define _MB_MAP_DIRECT
This approach provides a quick alternative if you don't want to use the default behavior or can't use inlining. A macro maps the generic-text routine to the MBCS version of the routine, as in the following example from TCHAR.H.
#define _tcschr _mbschr
When you take this approach, be careful to ensure that appropriate data types are used for string arguments and string return values. You can use type casting to ensure proper type matching or you can use the _TXCHAR
generic-text data type. _TXCHAR
maps to type char
in SBCS code but maps to type unsigned char
in MBCS code. For more information about generic-text macros, see Generic-text mappings.
END Microsoft Specific
See also
Internationalization
Universal C runtime routines by category
Feedback
https://aka.ms/ContentUserFeedback.
Coming soon: Throughout 2024 we will be phasing out GitHub Issues as the feedback mechanism for content and replacing it with a new feedback system. For more information see:Submit and view feedback for