Why is there a macro which defines _tmain?
Asked Answered
M

2

7

I am new to C++ coding, coming from Java and C# background. I'm puzzled by the proliferation of #define terms starting with the most basic:

#define _tmain wmain

When I first learned a smattering of C ages ago, the main function was:

int main(int argc, char *argv[])

In the Visual C++ project I created, it made the main function:

int _tmain(int argc, _TCHAR* argv[])

I'm just wondering why there needed to be a name translation from wmain to _tmain? Why not just use the original C main function prototype?

In general there seems to be lot of #define renaming something which looks pretty clear to start with, to something which looks more mysterious and less clear (I mean wmain to _tmain ??).

Thanks for tolerating what may be a very obvious question.

Montanez answered 8/2, 2011 at 18:47 Comment(3)
That's Windows-specific stuff, it has nothing to do with Standard C++ (nor C). They (at Microsoft) have a bad habit of horrible naming schemes and complicating things unnecessarily.Celka
Once upon a time, someone thought this was a good idea to help people migrate from older Windows versions using char to newer once using wchar_t. It wasn't, and now it just confuses people!Larceny
Related: https://mcmap.net/q/236655/-is-tchar-still-relevantWillful
C
13

This is a Visual C++-specific feature, it's not a part of C++.

Most of the Windows API functions have two versions: those that end in W, which are for use with wide character strings (wchar_t strings) and those that end in A, which are for use with narrow character strings (char strings). The actual Windows API "functions" don't have any suffix and are defined as macros that expand to the right version depending on the settings.

The T names (like _TCHAR and _tmain) are for the same purpose: they are macros that expand to the right name depending on your compilation settings, so wchar_t and wmain for wide character support, or char and main for narrow character support.

The idea is that if you write your code using the character-type-agnostic names (the T names), you can compile your code to use narrow characters (ASCII) or wide characters (Unicode) without changing it. The tradeoff is that your code is less portable.

Clime answered 8/2, 2011 at 18:51 Comment(8)
Thanks very much. That's a great overview. From a practical standpoint, do most developers try to avoid the Visual C++ conventions to stick with standard C++, or is the assumption that if you are developing on Windows, just use the Visual C++ conventions?Montanez
@Sam: That depends. If you are writing code that makes heavy use of the Windows API, it may be very useful for you to use TCHAR and friends. If you are writing code that needs to be portable across multiple platforms, then you don't want to use TCHAR and friends. I've done very little Windows-specific C++ programming, so I'm probably not the best person to ask. All of the major projects I've worked on in C++ have had portability as a top requirement.Clime
@Sam: Since you say that you are new to C++ programming, I would highly recommend that you learn to write portable C++ first and learn to avoid language extensions and platform-specific features wherever possible. Try to write platform-dependent code only when you must (e.g., when you have to interoperate with the OS or use functionality not accessible through the C++ Standard Library). When you do have to use platform-specific code, try to isolate it as much as possible so that you can port the code easily to other platforms if you have to.Clime
@Sam: Just in case you are in need of one, there is a list of good introductory C++ books. Most C++ books aren't worth the paper they are printed on, so if you don't have one I'd highly recommend getting one of those.Clime
@James: It is slighly useful only if you target different Windows releases with varying APIs. There aren't any, anymore. So you can just as well use wchar_t, which is what the TCHAR macro expands to.Larceny
@Bo: True, except that there's a lot of code still out there that is not Unicode-aware and many libraries have to work with both Unicode- and non-Unicode programs, and that's where the TCHAR and friends are more useful.Clime
@James: thanks for the book recommendations. I like the book recommendations. (My only book at the moment is an older Teach Yourself C++ book.) I think the key thing for me, is to try to translate what I know how to do in Java (and C#) to C++ as quickly as possible. I kind of want to eliminate as much "cruft" and over complexity as possible. I'm going to take the suggestion to start with standard C++, and then learn whatever Windows specific practices I need at the end. (My desktop is Windows XP, but our runtime environment is Linux.)Montanez
@James: Most libraries aren't overloaded for char and wchar_t the way the Windows API is.Willful
E
5

Because Microsoft decided that the best way to add Unicode support to C++ was to add a TCHAR type, which is #defined to either char or wchar_t depending on the value of Project Properties > Configuration Properties > General > Character Set. _tmain is also #defined to either main (which takes chars) or wmain (which takes wchar_ts) depending on that setting.

Ecthyma answered 8/2, 2011 at 18:52 Comment(3)
@Sam: Unfortunately the Windows OS group are C specialists, so they used #define instead of typedef, and macros instead of inline functions. This introduced thousands of nasty macros into the windows headers, which you will notice when one of them accidentally matches one of your function names. :-(Larceny
Unix developers, on the other hand, decided that the best way to add Unicode support to C++ was to use UTF-8.Willful
@BoPersson - ...most notably the max and min macros, which actually hose the stl.Accusatorial

© 2022 - 2024 — McMap. All rights reserved.