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.

Dr1Ku
  • 2,875
  • 3
  • 47
  • 56
Sam Goldberg
  • 6,711
  • 8
  • 52
  • 85
  • 7
    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. – eq- Feb 08 '11 at 18:51
  • 2
    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! – Bo Persson Feb 08 '11 at 23:13
  • 1
    Related: http://stackoverflow.com/questions/234365/is-tchar-still-relevant – dan04 Feb 10 '11 at 05:20

2 Answers2

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.

James McNellis
  • 348,265
  • 75
  • 913
  • 977
  • 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? – Sam Goldberg Feb 08 '11 at 21:24
  • @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. – James McNellis Feb 08 '11 at 21:31
  • 2
    @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. – James McNellis Feb 08 '11 at 22:44
  • @Sam: Just in case you are in need of one, there is [a list of good introductory C++ books](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). 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. – James McNellis Feb 08 '11 at 22:46
  • 1
    @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. – Bo Persson Feb 08 '11 at 23:19
  • @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. – James McNellis Feb 08 '11 at 23:21
  • 1
    @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.) – Sam Goldberg Feb 09 '11 at 18:17
  • @James: Most libraries aren't overloaded for `char` and `wchar_t` the way the Windows API is. – dan04 Feb 10 '11 at 02:42
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.

John Calsbeek
  • 35,947
  • 7
  • 94
  • 101
  • 2
    @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. :-( – Bo Persson Feb 08 '11 at 23:25
  • 1
    Unix developers, on the other hand, decided that the best way to add Unicode support to C++ was to use UTF-8. – dan04 Feb 10 '11 at 00:54
  • 1
    @BoPersson - ...most notably the max and min macros, which actually hose the stl. – T.E.D. Jun 25 '12 at 19:51