由于没有__attribute__((preconstructor))
,您可以使用某些节属性将代码粘贴到相关节中。
#include <stdio.h>
int v;
int w;
int x;
__attribute__((constructor)) static void
foo(void)
{
printf("Foo %d %d %d\n", v, w, x);
}
static void
bar(void)
{
v = 3;
}
static void
bar1(void)
{
w = 2;
}
static void
bar2(void)
{
x = 1;
}
__attribute__((section(".preinit_array"))) static void (*y[])(void) = { &bar, &bar1, &bar2 };
int
main(int argc, char **argv)
{
printf("Hello World\n");
}
文件倒入foo.c
,编译使用:gcc -o foo foo.c
,然后运行产生一个的输出:使用
Foo 3 2 1
Hello World
文件编译,然后运行产生相同的输出,所以也出现与静态链接的二进制文件一起工作。
它会不是与.so
文件,但;链接器抱怨:
/usr/bin/ld: /tmp/ccI0lMgd.o: .preinit_array section is not allowed in DSO
/usr/bin/ld: failed to set dynamic section sizes: Nonrepresentable section on output
我倾向于避免它,因为在该部分运行的代码先于所有其他初始化例程。如果你试图执行一些“这应该是第一次运行”的初始化,那么它确实不是一个好主意 - 你只是在与一些其他机制应该解决的竞争条件作斗争。
你有关于'__preinit_array_start'预期用途的任何信息吗?它看起来非常没有证件。 – pts
唯一可以在任何真实细节中解释的参考是[System V ABI](http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#init_fini)。它适用于可执行文件的自包含初始化代码。该代码在最早的启动点运行(即在所有内容已经映射之后,但在调用构造函数之前)。在这种情况下,不能保证任何库代码都能正常工作,例如const对象在此时不可用。 – Petesh