我希望在main
开始之前运行一些代码,然后运行静态变量的构造函数。我可以使用代码like this (ideone)
extern "C" {
static void do_my_pre_init(void) {
// something
}
__attribute__ ((section (".preinit_array"))) void(*p_init)(void) = &do_my_pre_init;
}
由于_init
和.init_array
尚未执行,是否有任何语言功能在此功能中执行时无效?
或者只是用户代码应该挂钩到这个机制?
__libc_init_array
typical __libc_init_array
的来源类似于:
static void __libc_init_array() {
size_t count, i;
count = __preinit_array_end - __preinit_array_start;
for (i = 0; i < count; i++)
__preinit_array_start[i]();
_init();
count = __init_array_end - __init_array_start;
for (i = 0; i < count; i++)
__init_array_start[i]();
}
__...
符号来自包含
. = ALIGN(4);
__preinit_array_start = .;
KEEP (*(.preinit_array))
__preinit_array_end = .;
. = ALIGN(4);
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
答案 0 :(得分:1)
由于_init和.init_array尚未执行,是否有任何语言功能在此功能中执行时无效?
这个问题不可能回答一般,因为语言本身没有.preinit_array
,_init
或.init_array
的概念。所有这些概念都是特定系统的实现详细信息。
实际上,您并不能确保任何工作。像malloc
这样简单的事情可能无效(例如,因为malloc
子系统本身可能正在使用.preinit_array
来初始化自己)。
实际上,在基于GLIBC的平台上使用动态链接,大多数都可以工作(因为libc.so.6
在主可执行文件的第一条指令运行之前很久就会初始化。)
对于全静态可执行文件,所有投注均已关闭。
对于非GLIBC平台,您需要查看该平台的具体内容(并且您不太可能找到任何保证)。
更新
我可以进行函数调用吗,
函数调用不需要使用全静态链接进行设置,并且需要动态加载器在动态链接情况下进行初始化。
表示,动态加载器在完全初始化之前不会在应用程序中开始执行代码,因此函数调用应该是安全的。指定结构
在C
中,充其量只是一些说明。最糟糕的是,这是对memcpy
或memset
的调用。这应该是安全的。
使用数组初始值设定项。
这只是结构分配的一个特例,所以应该是安全的。