__attribute__ ((<attibute>))
可用于执行main()
之前和之后的函数,如constructor
(作为设置函数)和destructor
(作为清除函数)。令我惊讶的是,如果参数也被传递,即使这两个编译也运行正常。
#include <stdio.h>
void myStartupFunction (int a, int b) __attribute__ ((constructor));
void myDestructorFunction (int a, int b) __attribute__ ((destructor));
void myStartupFunction (int a, int b)
{
printf("Before main\n");
}
void myDestructorFunction (int a, int b)
{
printf("After main\n");
}
int main()
{
printf("Inside main\n");
return 0;
}
但由于我无法控制(也许我错了)调用和执行这两个函数,为什么要提供这样的功能。我的意思是,如果做出这样的定义,谁会将参数传递给这些函数?如果OS调用这两个函数,它决定传递什么参数以及如何?
答案 0 :(得分:1)
这是C和POSIX标准的未定义行为(基于C标准)。程序执行的起点是main
,5.1.2.2.1。其他任何事情都超出了标准的任何保证。
__attribute__
语法不是Linux的一部分,甚至与它无关。它是一个gcc(可能还有其他类似的clang)扩展,它部分地为静态变量提供C ++初始化。
但是,gcc不保证您可以在这些扩展中使用标准库函数。实际上,它不能,因为它不控制应用程序启动代码,也不控制系统库。
此启动代码/运行时环境(又名C运行时,“crt”)负责设置静态变量,初始化标准库(例如malloc
和朋友的内存管理)等。它也称这些“构造者”。
因此,您必须从运行时环境和库中获得保证如果您想使用此类构造。一般来说,还有其他更安全/标准的方法可以实现您想要的任何目标。例如。明确地在main
中呼叫它们或自动生成呼叫。这样你就可以完全控制你传递的参数和方法。
注意:__attribute__
通常与“运行功能”无关。它只是为函数(或类型,变量等)添加其他约束/特性,或告诉编译器特殊用法。只有"constructor"
和"destructor"
属性与您要求的行为相关。
gcc documentation并未强制要求功能的特定签名。大概这是留给运行时。您可能想要检查目标环境。