开发者

What does a C++ compiler do to create an object?

开发者 https://www.devze.com 2022-12-09 02:01 出处:网络
In C code like such: { int i = 5; /* ....... */ } The compiler will replace the code by moving the Stack pointer down (for stacks growing down) by the size of an int, and places the value 5 in that

In C code like such:

{
   int i = 5;
   /* ....... */
}

The compiler will replace the code by moving the Stack pointer down (for stacks growing down) by the size of an int, and places the value 5 in that memory place.

Similarly, in C++ code, what does the compiler do if an object is created? For example:

class b
{
   public :
           int p;
           virtual void fun();
};

main()
{
   b   obj;
}

What will the compiler do for the above code? Can anyone explain when memory is allocated, and when开发者_如何学Go memory for the virtual table is allocated, and when the default constructor is called?


On Constructions

Logically there is no difference between the two:

In both case the stack is made large enough to hold the obect and the constructor is called on the object.

Just note:

  • The constructor for a POD type does nothing.
  • A user defined type with no constructor has a compiler generated default cosntructor.

You can think about it like this:

int   x;  // stack frame increased by sizeof(int) default construct (do nothing)
B     a;  // stack frame increased by sizeof(B)   default construct.

While:

int   y(6);  // stack frame increased by sizeof(int) Copy constructor called
B     b(a);  // stack frame increased by sizeof(B)   Copy constructor called

Ok. Of course the constructor for POD types is very trivial and the compiler will do a lot of optimizations (and may all but remove any actual code and even the memory address), but logically it is just fine to think of it happining this way.

Note: All types have a copy constructor (the compiler defines one if you don't) and the POD types you can logically think of it as copy construcion without any problems.

As for virtual tables:

Let me first note this is an implementation detail and not all compilers use them.
But the vtable itself is usually generated at compile time. Any object that needs a vtable has an invisable pointer added to the structure (this is included as part of the objects size). Then during contruction the pointer is set to point at the vtable.

Note: It is impossable to define when the vtable is set as this is not defined by the standard and thus each compiler is free to do it at any time. If you have a multiple level hierarchy then the vtable is probably set by each constructor from base to most derived and thus probably wrong until the final constructor finishes.

Note: You can not call virtual functions in the constructor/destructor. So all you can say is that the vtable will be correctly initialised only after the constructor has fully completed.


It's semantically the same, the stack pointer gets decremented (for stacks growing down) by sizeof b, then the default constructor is called to set up your instance.

In practice, depending on your architecture and on your compiler (and the flags you pass to it), basic types like in your int example may not get allocated actual memory space on the stack unless it's really required. They'll live in registers until an operation requiring a real memory address is needed (like the & operator).


To touch on question about when the virtual table get's allocated. Usually it does done at compile time (though it does depend on the compiler).

The virtual table is static for any given class. Because of this the compiler can emit the table at compile time. During the initialization of the class the pointer to the virtual table is set to the stored table.

Because of this different instances of the same class will point to the same virtual table.


On

   b   obj;

as with an int, the stack pointer is increased by the size of b. Then the constructor is called. The constructor may or may not call new or any other function to allocate memory. Thats up to the b's implementation. The call itself does not initiate any allocation.

The vftable is a static object. It is not created with the object itself. The object rather contains a 'invisible' pointer that points to its matching vftable. Its size is include in sizeof(b).


Just to add to previous answers, once the object is constructed, the compiler will do whatever magic is necessary under it's conventions to guarantee the destructor is called when the object goes out of scope. The language guarantees this, but most compilers have to do something to follow through on the guarantee (like set up a table of pointers to destructors and rules about when to invoke the various destructors for the various objects).


According to Itanium C++ ABI standard (which, for example, GCC follows), virtual table is stored into a separate memory, global to the translation unit.

For each dynamic class a virtual table is constructed and is stored under specific name in the object file, like _ZTV5Class. Classes, whose runtime type is exactly Class will contain pointers to this table. These pointers will be initialized, adjusted and accessed, but no class contains its virtual table within its instance.

So the answer is that virtual tables are allocated at compile time, and during construction only pointers to them are set up.

0

精彩评论

暂无评论...
验证码 换一张
取 消