text: .
  However in C and C++ programs the entry point is not main(). The entry point is a procedure that the compiler provides. This procedure will perform some initializations, it will initialize the C/C++ run-time library. This involves opening the 3 standard I/O handles and perhaps initializaing some global data structures. Also the heap will be set up. There may be other initializations to be done as well. In a C++ program, the entry point function will probalby also call the constructors for all the global objects defined in the program. Then the entry point function will call your main().
  If you are using Visual C++, take a look at the C Run-Time Library function source code - crt0.c, which contains the actual startup routine.
  >> usually something like I mentioned
  >> preivously _main() of the
  >> compiler
  The _main() you see is the main() that you wrote. Underscores are usually prepended to function names of functions with "c" linkage on most implimentations.
  Now you are sure that your main function is the first.
  But do not try to call C runtime library functions - use only API. You will get really small Win Application.
  From MSDN
  //////////////////////
  C++ Q & A
  Under the Hood
  Matt Pietrek
  Matt Pietrek is the author of Windows 95 System Programming Secrets (IDG Books, 1995). He works at Nu-Mega Technologies Inc., and can be reached at 71774.362@compuserve.com.
  Q
  AIn.
  Size Does Matter?
  So Why Are Executables Fat?.
  Figure 1 TEST.MAP from Visual C++ 4.1
  0001:00000000 _main 00401000 f test.obj
  0001:00000010 _mainCRTStartup 00401010 f LIBC:crt0.obj
  0001:00000120 __amsg_exit 00401120 f LIBC:crt0.obj
  0001:00000150 __cinit 00401150 f LIBC:crt0dat.obj
  0001:00000180 _exit 00401180 f LIBC:crt0dat.obj
  0001:000001a0 __exit 004011a0 f LIBC:crt0dat.obj
  0001:00000290 __global_unwind2 00401290 f LIBC:exsup.obj
  0001:000002d2 __local_unwind2 004012d2 f LIBC:exsup.obj
  0001:0000032a __NLG_Return2 0040132a LIBC:exsup.obj
  0001:0000033a __abnormal_termination 0040133a f LIBC:exsup.obj
  0001:0000035d __NLG_Notify1 0040135d f LIBC:exsup.obj
  0001:00000366 __NLG_Notify 00401366 f LIBC:exsup.obj
  0001:00000379 __NLG_Dispatch 00401379 LIBC:exsup.obj
  0001:00000380 __XcptFilter 00401380 f LIBC:winxfltr.obj
  0001:00000510 __setenvp 00401510 f LIBC:stdenvp.obj
  0001:000005f0 __setargv 004015f0 f LIBC:stdargv.obj
  0001:00000870 ___crtGetEnvironmentString
  0001:00000a10 __setmbcp 00401a10 f LIBC:mbctype.obj
  0001:00000cd0 ___initmbctable 00401cd0 f LIBC:mbctype.obj
  0001:00000ce0 __ioinit 00401ce0 f LIBC:ioinit.obj
  0001:00000ec0 __heap_init 00401ec0 f LIBC:heapinit.obj
  0001:00000ee0 __except_handler3 00401ee0 f LIBC:exsup3.obj
  0001:00000f9d __seh_longjmp_unwind@4 00401f9d f LIBC:exsup3.obj
  0001:00000fc0 __FF_MSGBANNER 00401fc0 f LIBC:crt0msg.obj
  0001:00001000 __NMSG_WRITE 00402000 f LIBC:crt0msg.obj
  0001:000011f0 _free 004021f0 f LIBC:free.obj
  0001:00001210 _malloc 00402210 f LIBC:malloc.obj
  0001:00001230 __nh_malloc 00402230 f LIBC:malloc.obj
  0001:00001270 __heap_alloc 00402270 f LIBC:malloc.obj
  0001:00001290 ___crtMessageBoxA 00402290 f LIBC:crtmbox.obj
  0001:00001330 _strncpy 00402330 f LIBC:strncpy.obj
  0001:00001430 __callnewh 00402430 f LIBC:handler.obj
  0001:00001450 _RtlUnwind@16 00402450 f kernel32:KERNEL32.dll++.
  Figure 2 TEST.MAP from Borland C++ 5.0
  Address Publics by Value
  0001:0000007C _main
  0001:00000084 _memchr
  0001:000000A4 _memcpy
  0001:000000C8 _memmove
  0001:00000114 _memset
  0001:00000144 _strcmp
  0001:00000170 _strlen
  0001:0000018C _memcmp
  0001:000001D0 _strrchr
  0001:00000BBE _ThrowException(...
  0001:00000D57 _CatchCleanup()
  0001:0000117E __Local_unwind
  0001:000011FB __ExceptionHandler
  0001:00001B81 __CurrExcContext
  0001:00001F72 __tpdsc__[typeinfo*]
  0001:00001F89 __tpdsc__[Bad_typeid]
  0001:00001FA5 __tpdsc__[Bad_cast]
  0001:00001FC1 __tpdsc__[typeinfo]
  0001:0000200C @__InitExceptBlock
  0001:00002077 ___call_terminate
  0001:0000215B ___call_unexpected
  0001:000021CF __GetPolymorphicDTC(void*,
  0001:000021EE __ExceptInit
  0001:000022D0 __GetExceptDLLinfoInternal
  0001:0000230C __lockDebuggerData()
  0001:00002334 __unlockDebuggerData()
  0001:00002340 ___DefHandler
  0001:00002460 __InitDefaultHander
  0001:0000247A ___doGlobalUnwind
  0001:0000248F invokeHnd()
  0001:00002498 __SetExceptionHandler
  0001:000024AD __UnsetExceptionHandler
  0001:000024E0 _flushall
  0001:000024E8 __allocbuf
  0001:00002568 _fflush
  0001:000025F0 __flushout
  0001:00002650 __initfmode
  0001:00002660 ___fputn
  0001:00002734 _fputs
  0001:00002774 _fputc
  0001:0000290C _sprintf
  0001:0000298C __init_streams
  0001:00002B1C ___vprinter
  0001:0000317C __xfflush
  0001:000031BC __flushall
  0001:000031F4 __umask
  0001:000032C4 ___write
  0001:000033A4 __get_handle
  0001:000033E4 __dup_handle
  0001:00003504 __init_handles
  0001:00003648 ___IOerror
  0001:0000368C ___DOSerror
  0001:000036AC ___NTerror
  0001:000036C0 __rtl_write
  0001:00003724 ___close
  0001:00003770 ___isatty
  0001:000037A0 ___isatty_osfhandle
  0001:000037B8 ___lseek
  0001:00003830 ___open
  0001:00003A28 __clear87
  0001:00003A3C __control87
  0001:00003A64 ___realcvt
  0001:00003A6A ___nextreal
  0001:00003A70 __scantod
  0001:00003A76 __scanrslt
  0001:00003A7C __fpreset
  0001:00003AAC ___longtoa
  0001:00003B20 ___utoa
  0001:00003B3C __matherr
  0001:00003B68 __matherrl
  0001:00003B98 __initmatherr
  0001:000041B8 _free
  0001:000042C0 ___org_malloc
  0001:000042C0 _malloc
  0001:00004754 _realloc
  0001:000047EC operator delete(void*)
  0001:000047FC operator delete[](void*)
  0001:0000480C __virt_reserve
  0001:00004878 __virt_commit
  0001:000048CC __virt_decommit
  0001:000048F0 __virt_release
  0001:00004978 __ErrorMessage
  0001:00004A68 __ErrorExit
  0001:00004AE0 __ErrorMessageHelper
  0001:00004B90 __abort
  0001:00004BA4 _abort
  0001:00004C10 _exit
  0001:00004C28 __exit
  0001:00004C60 __initwild
  0001:00004E5C __addarg
  0001:00005180 _raise
  0001:000051F8 __create_shmem
  0001:00005200 __init_exit_proc
  0001:000052AC __startup
  0001:00005414 __cleanup
  0001:0000548C __terminate
  0001:000054A0 _getdate.
  Breaking It Down
  .
  The TINYCRT Library.
  Figure 3 CRT0TWIN.C
  //========================
  // TINYCRT - Matt Pietrek 1996
  // Microsoft Systems Journal, October 1996
  // FILE: CRT0TWIN.C
  //========================
  #include <windows.h>
  #ifndef __BORLANDC__
  // Force the linker to include KERNEL32.LIB
  #pragma comment(linker, "/defaultlib:kernel32.lib"
  #endif
  //
  // Modified version of the Visual C++ 4.1 startup code. Simplified to
  // make it easier to read. Only supports ANSI programs.
  //
  void __cdecl WinMainCRTStartup( void )
  {
  int mainret;
  char *lpszCommandLine;
  STARTUPINFO StartupInfo;
  lpszCommandLine = GetCommandLine();
  // Skip past program name (first token in command line).
  if ( *lpszCommandLine == '"' ) //Check for and handle quoted program name
  {
  // Scan, and skip over, subsequent characters until another
  // double-quote or a null is encountered
  while( *lpszCommandLine && (*lpszCommandLine != '"') )
  lpszCommandLine++;
  // If we stopped on a double-quote (usual case), skip over it.
  if ( *lpszCommandLine == '"' )
  lpszCommandLine++;
  }
  else // First token wasn't a quote
  {
  while ( *lpszCommandLine > ' ' )
  lpszCommandLine++;
  }
  // Skip past any white space preceeding the second token.
  while ( *lpszCommandLine && (*lpszCommandLine <= ' ') )
  lpszCommandLine++;
  StartupInfo.dwFlags = 0;
  GetStartupInfo( &StartupInfo );
  mainret = WinMain( GetModuleHandle(NULL),
  NULL,
  lpszCommandLine,
  StartupInfo.dwFlags & STARTF_USESHOWWINDOW
  ? StartupInfo.wShowWindow : SW_SHOWDEFAULT );
  ExitProcess(mainret);
  }cA
  Figure 4 CRT0TCON.C
  //========================
  // TINYCRT - Matt Pietrek 1996
  // Microsoft Systems Journal, October 1996
  // FILE: CRT0TCON.C
  //========================
  #include <windows.h>
  #include "argcargv.h"
  #ifndef __BORLANDC__
  // Force the linker to include KERNEL32.LIB
  #pragma comment(linker, "/defaultlib:kernel32.lib"
  #endif
  int __cdecl main(int, char **, char **); // In user supplied code
  void __cdecl mainCRTStartup( void )
  {
  int mainret, argc;
  argc = _ConvertCommandLineToArgcA
  mainret = main( argc, _ppszArgv, 0 );
  ExitProcess(mainret);
  }.
  Figure 5 ARGCARGV.C
  //========================
  // TINYCRT - Matt Pietrek 1996
  // Microsoft Systems Journal, October 1996
  // FILE: ARGCARGV.C
  //========================
  #include <windows.h>
  #include "argcargv.h"
  #define _MAX_CMD_LINE_ARGS 128
  char * _ppszArgv[_MAX_CMD_LINE_AR
  int __cdecl _ConvertCommandLineToArgcA
  {
  int cbCmdLine;
  int argc;
  PSTR pszSysCmdLine, pszCmdLine;
  // Set to no argv elements, in case we have to bail out
  _ppszArgv[0] = 0;
  // First get a pointer to the system's version of the command line, and
  // figure out how long it is.
  pszSysCmdLine = GetCommandLine();
  cbCmdLine = lstrlen( pszSysCmdLine );
  // Allocate memory to store a copy of the command line. We'll modify
  // this copy, rather than the original command line. Yes, this memory
  // currently doesn't explicitly get freed, but it goes away when the
  // process terminates.
  pszCmdLine = HeapAlloc( GetProcessHeap(), 0, cbCmdLine+1 );
  if ( !pszCmdLine )
  return 0;
  // Copy the system version of the command line into our copy
  lstrcpy( pszCmdLine, pszSysCmdLine );
  if ( '"' == *pszCmdLine ) // If command line starts with a quote ("),
  { // it's a quoted filename. Skip to next quote.
  pszCmdLine++;
  _ppszArgv[0] = pszCmdLine; // argv[0] == executable name
  while ( *pszCmdLine && (*pszCmdLine != '"') )
  pszCmdLine++;
  if ( *pszCmdLine ) // Did we see a non-NULL ending?
  *pszCmdLine++ = 0; // Null terminate and advance to next char
  else
  return 0; // Oops! We didn't see the end quote
  }
  else // A regular (non-quoted) filename
  {
  _ppszArgv[0] = pszCmdLine; // argv[0] == executable name
  while ( *pszCmdLine && (' ' != *pszCmdLine) && ('\t' != *pszCmdLine) )
  pszCmdLine++;
  if ( *pszCmdLine )
  *pszCmdLine++ = 0; // Null terminate and advance to next char
  }
  // Done processing argv[0] (i.e., the executable name). Now do th
  // actual arguments
  argc = 1;
  while ( 1 )
  {
  // Skip over any whitespace
  while ( *pszCmdLine && (' ' == *pszCmdLine) || ('\t' == *pszCmdLine) )
  pszCmdLine++;
  if ( 0 == *pszCmdLine ) // End of command line???
  return argc;
  if ( '"' == *pszCmdLine ) // Argument starting with a quote???
  {
  pszCmdLine++; // Advance past quote character
  _ppszArgv[ argc++ ] = pszCmdLine;
  _ppszArgv[ argc ] = 0;
  // Scan to end quote, or NULL terminator
  while ( *pszCmdLine && (*pszCmdLine != '"') )
  pszCmdLine++;
  if ( 0 == *pszCmdLine )
  return argc;
  if ( *pszCmdLine )
  *pszCmdLine++ = 0; // Null terminate and advance to next char
  }
  else // Non-quoted argument
  {
  _ppszArgv[ argc++ ] = pszCmdLine;
  _ppszArgv[ argc ] = 0;
  // Skip till whitespace or NULL terminator
  while ( *pszCmdLine && (' '!=*pszCmdLine) && ('\t'!=*pszCmdLine) )
  pszCmdLine++;
  if ( 0 == *pszCmdLine )
  return argc;
  if ( *pszCmdLine )
  *pszCmdLine++ = 0; // Null terminate and advance to next char
  }
  if ( argc >= (_MAX_CMD_LINE_ARGS) )
  return argc;
  }
  }
  As a side benefit to writing my own argc/argv processing, you can use the _ConvertCommandLineToArgcA
  RTL Routines.
  Figure 6 PRINTF.C
  #include <windows.h>
  #include <stdio.h>
  #include <stdarg.h>
  #ifndef __BORLANDC__
  // Force the linker to include USER32.LIB
  #pragma comment(linker, "/defaultlib:user32.lib")
  #endif
  int __cdecl printf(const char * format, ...)
  {
  char szBuff[1024];
  int retValue;
  DWORD cbWritten;
  va_list argptr;
  va_start( argptr, format );
  retValue = wvsprintf( szBuff, format, argptr );
  va_end( argptr );
  WriteFile( GetStdHandle(STD_OUTPUT_HA
  &cbWritten, 0 );
  return retValue;
  }.
  Figure 7 ISCTYPE.C
  // 1996 - John Robbins, with Matt Pietrek
  #include <ctype.h>
  int __cdecl _isctype ( int c , int mask )
  {
  /* c valid between -1 and 255 */
  if (((unsigned)(c + 1)) <= 256)
  {
  return ( _pctype[c] & mask ) ;
  }
  else
  return 0;
  }.
  Using TINYCRT with Visual C++.
  Using TINYCRT with Borland.
  Wrap!
  Experts Exchange Solution brought to you by
  Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.Start your 7-day free trial
  That is, the program has a startup routine that parses the command line, and does other initialisations then calls you main function, and tidies up at the end.
  There is no stadard function that does this. The actual routine is compiler / library / linker dependant - not even just OS dependant. Unless you go to the trouble of defining your own runtime library, you will ususally get teh standard compiler/library/linker supplied startup routine.
  I think nietod deserves the points for first answer the question (what calls main). His answer was succinct and understandable .. lathough the information is buried in the article above (if you read carefully) the article really doesn't say anything much more in answer to the original question (but is quite useful if you want to do your own startup code for ultimate size/speed for smaller aps).