传递给main()之前和之后执行的函数的参数

时间:2016-06-14 18:20:37

标签: c linux

__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调用这两个函数,它决定传递什么参数以及如何?

1 个答案:

答案 0 :(得分:1)

这是C和POSIX标准的未定义行为(基于C标准)。程序执行的起点是main5.1.2.2.1。其他任何事情都超出了标准的任何保证。

__attribute__语法不是Linux的一部分,甚至与它无关。它是一个gcc(可能还有其他类似的clang)扩展,它部分地为静态变量提供C ++初始化。

但是,gcc不保证您可以在这些扩展中使用标准库函数。实际上,它不能,因为它不控制应用程序启动代码,也不控制系统库。

此启动代码/运行时环境(又名C运行时,“crt”)负责设置静态变量,初始化标准库(例如malloc和朋友的内存管理)等。它也称这些“构造者”。

因此,您必须从运行时环境和库中获得保证如果您想使用此类构造。一般来说,还有其他更安全/标准的方法可以实现您想要的任何目标。例如。明确地在main中呼叫它们或自动生成呼叫。这样你就可以完全控制你传递的参数和方法。

注意:__attribute__通常与“运行功能”无关。它只是为函数(或类型,变量等)添加其他约束/特性,或告诉编译器特殊用法。只有"constructor""destructor"属性与您要求的行为相关。

gcc documentation并未强制要求功能的特定签名。大概这是留给运行时。您可能想要检查目标环境。