Parses the function called before the main function and its effect on the design

  • 2020-04-01 23:37:53
  • OfStack

The other day, write a simple test framework for new employees that allows them to easily write test cases and execute them. One problem was how to get them to add test cases without affecting the test framework? The singleton pattern in c++ solves this problem, but one of the difficulties is registering singleton before main. C ++ can be registered through the constructor, how to register c?
Finally, check the data, the original can be defined in the main before the function called! This feature improves the modular design of c.
Feature description:
If you want to define a function to be called before the main function, you can add "successively attribute__((constructor)" after the declaration of the function, as follows:
Int before () __attribute__ ((constructor));
If you want to define a function to be called after main, you can add "s attribute__((destructor))" after the declaration of the function, as follows:
Int after () __attribute__ ((destructor));
As you can see, it should be similar to constructs and destructions in c++.

Some details:
Write test code to test this program, found a few:
1. Before is called before main. Before the call, each global variable has been initialized. That is, these functions are called after the global variable is initialized and before the main function. This is very important, otherwise it may cause a lot of problems.
2. After is called after main, but there is a special point that must be in the main return to execute, otherwise, need to execute some function through atexit. This feature isn't much use to me right now.
3. Functions called before main can be declared static.
4. Multiple functions can be called before the main function. There is a problem here, which is the order in which these functions are called. The problem is first of all a design problem, that is, we should design these functions to be order independent. In addition, the order of invocation is related to the order of compilation. I compiled with make under Linux and found that the function in the last compiled source file would be called first.
5. You can define such functions in both dynamic and static libraries.

With the effect on the design:
1, can optimize the single - piece mode in c++. Refer to design pattern
One of the biggest features of the singleton pattern is the ability to connect singlets while running. If a conditional statement is used to determine which singleton to use, the set of possible singlets is rigidly defined. Therefore, the concept of a single registry is introduced in the book, and the initialization of the single registry is adopted as follows:
First, define a singleton class, and call the singleton registration function to register itself in the constructor of the singleton class:

MySingleton::MySingleton()
{
...
Singleton::Register("MySingleton", this);
}

How is this function called? You can define a static instance:
The static MySingleton theSingleton;
This is done by calling MySingleton's constructor to construct the static instance before the main function, thus registering it like a registry.
There is a downside to this scenario: one of the prerequisites for its success is that theSingleton registry list must exist before theSingleton can be instantiated or it will fail. If MySingleton had applied other global variables, they might not have been initialized at this point.
One solution to this problem is to move the time of the singleton registration from the constructor to the function called before the main function.
Definition function:

static void before_main()
{
Singleton::Register("MySingleton", &theSingleton);
}
 Statement: 
staitc void before_main()__attribute__((constructor));

Before_main is called before the main function, and the global variables are all initialized when called, thus avoiding the above problem.
In fact, singleton can be used not only in c++ (object-oriented), but also in c. And with this feature of c, singletons work better.
2. Build the plug-in development framework without changing it.
One of the problems with building a plug-in development framework is how to add a plug-in and invoke the plug-in code without modifying the main framework code. The plug-in registration mechanism is typically used. That is, the framework provides external registration interfaces that plug-ins use to register. One possible solution for c to implement this functionality is to define a function that executes before main in the plug-in, where the plug-in registration interface is called to complete the registration. Note: the static loading of plug-ins is discussed here.
3, a module has some initialization work to do, using this mechanism can not change the main or function.
Aside from the plug-in framework, there are many optimizations that can be made to the modularity of c using this feature. For example, you can initialize each module before main to prevent frequent changes to main.
Note: the environment described in this article is Linux c, c++.

Related articles: