Q: How can I perform operations before the main () function in C ++?

Source: Internet
Author: User

Q: How can I perform operations before the main () function in C ++?

The first reaction is that the main () function is the start of all function execution. But the problem is how to execute the main () function before it is executed?

Think of the theapp object of the C ** app class in MFC, And the execution sequence is before the main function. The principle is the same. Let me think of it as follows:If the global object of a class is declared before the main function. The execution sequence of the global object must be prior to the main function according to the lifetime and scope of the global object.

Example:

Class simpleclass {public: simpleclass () {cout <"simpleclass constructor .. "<Endl; // step2 }}; simpleclass g_objectsimple; // Step1 Global Object int _ tmain (INT argc, _ tchar * argv []) // step 3 {return 0;}. You can view the execution sequence in step 1, step 2, and step 3.

 

Considering Global Objects, we will further consider the scope of static objects.The above example is further extended as follows:

Class simpleclass {public: simpleclass () {cout <"simpleclass constructor .. "<Endl; // step2 }}; class simpleclasstwo {public: static simpleclass m_ssimpleclass ;}; simpleclass simpleclasstwo: m_ssimpleclass = simpleclass (); // Step1 static object int _ tmain (INT argc, _ tchar * argv []) // Step3 {return 0 ;} you can view the execution sequence in One-Step debugging: Step 1, step 2, and step 3.

So far, we can conclude that the global object defined before the main () function and the constructors of static objects are executed before the main () function.

Further thinking, since we can execute the global and static object constructors before the main () function. Is there any function to be executed after the main () function?

Yes, the onexit function. The prototype is as follows:

_ Onexit_t _ onexit (

_ Onexit_t Function

);

_ Onexit_t_m _ onexit_m (

_ Onexit_t_m Function

);

Explanation: The _ onexit function is passed the address of a function (function) to be called when the program terminates normally. successive callto _ onexit create a register of functions that are executed in LIFO (last-in-first-out)
Order. The functions passed to _ onexit cannot take parameters.

 

Core points:

1) execution period-when the execution of the program is terminated;

2) Pass the parameter-the address of the function, that is, the function pointer;

3) execution sequence-post-in-first-out.

 

_ Onexit is a Microsoft extension. For ANSI portability, use atexit. The _ onexit_m version of the function is for mixed mode use.

Onexit is an extended version of Microsoft, and atexit is applied in Standard C ++.

[Msdn] example:

#include <stdlib.h>#include <stdio.h>/* Prototypes */int fn1(void), fn2(void), fn3(void), fn4 (void);int main( void ){      _onexit( fn1 );      _onexit( fn2 );      _onexit( fn3 );      _onexit( fn4 );      printf( "This is executed first.\n" );} int fn1(){      printf( "next.\n" );      return 0;} int fn2(){      printf( "executed " );      return 0;} int fn3(){      printf( "is " );      return 0;} int fn4(){      printf( "This " );      return 0;}

The execution result is as follows:

Obviously, the read program can see that the onexit () function is executed after the main () function is executed.

Is there any special case? Continuous discussion and updating ......


Update

Supplement: How is the console interface application started?

Take windows as an example. When Microsoft Visual Studio is used to create an application project, various connection switches are set in the integrated development environment, enables the linker to embed the correct type of subsystem into the final executable file (executable. For console interface applications, the switch of this linker is/subsystem: console.

When you start an application, the loader of the operating system checks the file header of the executable file image and obtains the value of this subsystem. As shown in, if the subsystem value is/subsystem: console, the loader automatically ensures that there is an available text Console window when the command operator starts the program. In addition, if necessary, a new window will be created when you start the Cui program from the resource manager.

When connecting the executable file, the linker selects the correct C/C ++ runtime to start the function. If/subsystem: console is specified, perform the following steps:

All C/C ++ runtime functions do the same thing. The difference 1 is that they process string types (ANSI strings or Unicode strings ), the difference 2 is the entry point function they call.

The use of the source code startup function of Visual C ++ comes with C ++ Runtime Library is summarized as follows:

1) Obtain a pointer to the complete command line of the new process;

2) Get a pointer to the environment variable of the new process;

3) initialize the global variables of the C/C ++ Runtime Library.

4) initialize the heap used by the memory allocation function (malloc and calloc) of the C Runtime Library and other underlying I/O routines.

5)Call constructors of all global and static C ++ class objects.

5th explains why the constructor of global and static variables runs before the main () function.

 

After the entry point function returns, the start function calls the exit function of the C Runtime Library to pass the returned value (nmainretval) to it ). The exit function executes the following tasks:

1) Call the _ onexit function to call any registered function;

2) Call the destructor of all global and static C ++ class objects;

3) In debug generation, if the _ crtdbg_leak_check_df flag is set, the memory leakage report is generated by calling the _ crtdumpmemoryleaks function.

4) Call the exitprocess function of the operating system to pass in nmainretval. This will cause the operating system to kill our process and set its exit code.

The execution sequence of the exit () function is: 1), 2), 3), and 4 ).

 

The following code demonstrates the execution sequence of the exit function.

First, global object constructor, then execute the print Statement of main function, then execute _ onexit to register the function, and finally execute the Global Object destructor.

# Include <stdlib. h> # include <stdio. h> class simpleclass {public: simpleclass () {cout <"simpleclass constructor .." <Endl ;}~ Simpleclass () {cout <"~ Simpleclass Destructor .. "<Endl ;}}; simpleclass g_objectsimple; // 1 Global Object/* prototypes */INT fn1 (void), FN2 (void), fn3 (void ), FN4 (void); int main (void) {_ onexit (fn1); _ onexit (FN2); _ onexit (fn3); _ onexit (FN4 ); printf ("this is executed first. \ n ");} int fn1 () {printf (" next. \ n "); return0;} int FN2 () {printf (" executed "); return0;} int fn3 () {printf (" is "); return0 ;} int FN4 () {printf ("this"); return0 ;}



Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.