Why is the constructor / destructor defined the same as in g ++ the generated assembly code?
I wrote a simple C ++ program that defines a class like below:
#include <iostream>
using namespace std;
class Computer
{
public:
Computer();
~Computer();
};
Computer::Computer()
{
}
Computer::~Computer()
{
}
int main()
{
Computer compute;
return 0;
}
When I use g++
(Test is on x86 32-bit Linux with g ++ 4.6.3.) To build ctors
and dtors
, I get these definitions at the end of the section .ctors
.
.globl _ZN8ComputerC1Ev
.set _ZN8ComputerC1Ev,_ZN8ComputerC2Ev
.globl _ZN8ComputerD1Ev
.set _ZN8ComputerD1Ev,_ZN8ComputerD2Ev
After converting to the resulting assembly code, I figured out what _ZN8ComputerC1Ev
should be the function name that is used when constructing the class Computer
, and _ZN8ComputerC2Ev
this is the name of the class constructor Computer
. The same thing happens in the declaration and call of the destructor Computer
.
It seems like a table is built by linking the constructor and its implementation.
So my questions are:
-
What is actually this constructor / destructor information for?
-
Where can I find them in format
ELF
?
I dropped the related sections .ctors
and .init_array
, but I just can't find the metadata that defined the relationship between _ZN8ComputerC1Ev
and _ZN8ComputerC2Ev
...
source to share
There is no table here. .globl
and .set
- these are so-called assembly directives or pseudo-operators. They signal something to the assembler, but don't necessarily result in actual code or data being generated. From the docs :
.global
symbol,.globl
symbol
.global
makes the symbol visible told
. If you define a symbol in your partial program, its value is given to other partial programs that are associated with it. Otherwise, the symbol takes its attributes from the symbol with the same name from another file associated with the same program name.
.set
symbol, expressionSet character value to expression. This changes the symbol value and type to match the expression.
Thus, the snippet you specify simply ensures that the constructor is bindable in case it references other compilers. The only effect you usually see in the latest ELF is the presence of these symbols in the symbol table (if it has not been removed).
Now, you might be interested to know why you have two different names for the constructor (for example, _ZN8ComputerC1Ev
and _ZN8ComputerC2Ev
). The answer is somewhat tricky, so I'll link to another SO question that addresses it in detail:
source to share