对于全局对象,特殊情况下构造函数不会执行。如c++写的os。
链接器把构造函数放在start_ctors和end_ctors之间,所以我们可以这样做:
for (i = &start_ctors; i < &end_ctors; i++) {
foo = (CONSTRUCTOR_FUNC)*i;
foo(); /* 构造函数不能用 cout对象,这个时候控制台还没有初始化 */
}
push ebx
static_ctors_loop:
mov ebx, start_ctors
jmp .test
.body:
call [ebx]
add ebx,4
.test:
cmp ebx, end_ctors
jb .body
call kmain ; call kernel proper
static_dtors_loop:
mov ebx, start_dtors
jmp .test
.body:
call [ebx]
add ebx,4
.test:
cmp ebx, end_dtors
jb .body
cli ; stop interrupts
hlt ; halt the CPU
//LDFLAG= -melf_i386 -static -L ./ -T ./arch/$(ARCH)/linker.ld
//linker.ld
OUTPUT_FORMAT(elf32-i386)
OUTPUT_ARCH(i386)
ENTRY (_start)
SECTIONS{
. = 0x00100000;
.text :{
*(.text)
}
.data ALIGN (0x1000) : {
start_ctors = .;
*(.ctor*)
end_ctors = .;
start_dtors = .;
*(.dtor*)
end_dtors = .;
*(.data)
}
.rodata ALIGN (0x1000) : {
*(.rodata)
}
.data ALIGN (0x1000) : {
*(.data)
}
.bss : {
sbss = .;
*(COMMON)
*(.bss)
ebss = .;
}
}
引出一个特殊需求,全局对象按顺序构造,我们显然无法预知start_ctors表顺序。
一个可行的方法使用重载new,并用模板函数封装其执行:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
struct test_t
{
public:
test_t()
{
printf("construct of test_t()\n");
}
int a;
int b;
};
void * operator new (size_t size, void * place)
{
return place;
}
/* call the default constructor */
template <class object_t> void construct(object_t * ptr)
{
new (ptr) object_t();
}
test_t t;
int main(int argc, char* argv[])
{
construct(&t);
return 0;
}