5

I am currently working on a console application for Windows 10 and am wondering what the main() entry point should be.

In Jeffrey Richter and Christophe Nasarre's "Windows via C/C++" (2007) on page 69, it states:

Your Windows application must have an entry-point function...as a C/C++ developer, there are two possible entry-point function you can use:

int WINAPI _tWinMain(HINSTANCE hInstanceExe, HINSTANCE, PTSTR pszCmdLine, int nCmdShow);

int _tmain(int argv, TCHAR *argv[], TCHAR *envp[]);

The book goes on to identify that these two entry points are actually mapped to different entry points by the compiler, depending on whether the application is GUI or Console and whether Unicode is used.

I would like to use the correct entry point for a Win32 console app using Unicode, so I am assuming(?), I want the _tmain version, however when I open a new project in Visual Studio 2015 Community Edition and select "Win32 Console app", and then select "Console Application", I end up with main() like I'm used to under Linux:

int main()

Which entry point should I be using ?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
VariableX
  • 51
  • 1
  • 3
  • 1
    I'd use `wmain` and avoid `TCHAR` like the plague. http://stackoverflow.com/questions/2438049/what-is-the-difference-between-wmain-and-main – Retired Ninja Jul 14 '16 at 01:54
  • Thanks for the link. I agree - TCHAR (as I understand it), will map to wchar_t when UNICODE is define'd in the project (which VS 2015 CE defaults to), but is more of a holdover from when people had to worry about ANSI versus Unicode ? – VariableX Jul 14 '16 at 02:02
  • 2
    `TCHAR` in theory allows you to compile for ansi or unicode. In practice you'll either never compile for both or if you do it won't be the only thing you need to change. – Retired Ninja Jul 14 '16 at 02:05
  • Ok, that makes sense. Thank you. – VariableX Jul 14 '16 at 02:08
  • 1
    There isn't really anything wrong with main() either, unless you actually need the command-line arguments in Unicode. (Since the console's support for Unicode is pretty limited, I'm not sure how much using wmain() actually gains you in practice.) – Harry Johnston Jul 14 '16 at 02:25
  • 2
    If you are stuck using `main()` instead of `wmain()`, you can still use `GetCommandLineW()` and `CommandLineToArgvW()` in a console app to get Unicode command-line parameters. – Remy Lebeau Jul 14 '16 at 03:36
  • 3
    *"The book goes on to identify that these two entry points are actually mapped to different entry points by the compiler"* - This is done in *crt0.c*, a CRT implementation file that used to ship with Visual Studio up to and including 2013. It contains all the logic to deduce the user-provided entry point, and lots of helpful comments. Unfortunately, this file is missing from VS 2015. – IInspectable Jul 14 '16 at 09:00
  • 3
    @IInspectable - `mcrtexe.cpp` (near line 152) has the same block comment about entry points as `crt0.c`. I haven't traced all the logic to see if they match, but they look superficially similar. (Incidentally the comment at the top of `mcrtexe.cpp` calls the file `crtexe.c`) – theB Jul 14 '16 at 12:55

1 Answers1

-2

The first entry point (or a variation) is normally used for a GUI process:

int WINAPI _tWinMain(HINSTANCE hInstanceExe, HINSTANCE, PTSTR pszCmdLine, int nCmdShow);

The second entry point (or variation) is normally used for command-line process:

int _tmain(int argv, TCHAR *argv[], TCHAR *envp[]);

The entry point is set using the /ENTRY linker option. Visual Studio sets this for you when you create a GUI/Console project and often times you won't need to change it. See: https://msdn.microsoft.com/en-us/library/f9t8842e.aspx

The _T prefix is conventionally used when working with tchar.h. This allows the application (in theory) to be easily compiled as either "Ansi" or Unicode. You can read more about this in a previous answer:

What is the difference between _tmain() and main() in C++?

Community
  • 1
  • 1
jimc
  • 149
  • 2
  • 9
  • 1
    The entry points in the question and the entry point you set through the `/ENTRY` linker option are different things. The former are the signatures and symbols used by the CRT, the latter specifies the symbol as seen by the OS loader. – IInspectable Jul 14 '16 at 16:23