是否可以在不调用main函数的情况下调用函数?

时间:2014-11-10 07:02:22

标签: c

如果我们需要调用任何函数,我们需要从main或嵌套方式从main函数中调用它。程序始终从main函数开始。

//fun1.c
fun1(void){
/*Do something useful*/
return 0;
}

//main_fun.c
main(void){
fun1();
return 0;
}

如果我们不想使用main函数并希望直接调用fun1,该怎么办? 可以直接将程序计数器指向fun1地址,以便它从那里开始吗?

2 个答案:

答案 0 :(得分:2)

如果您正在使用GCC或Clang,则可以使用constructor函数属性。

__attribute__((constructor))
fun1(void){
// ...

这里详细介绍:How exactly does __attribute__((constructor)) work?

答案 1 :(得分:0)

C99以及C11(参见n1570,其最新草案,实际上是标准)标准定义了两种C实现(请参阅C syntax wikipage)。

  • 托管实现(对代码应用软件很有用,例如在Linux,POSIX或者可能是Windows上)为您提供standard C librarylibc) - 给予{{1}来自malloc的{​​{1}}和来自<stdlib.h>等的printf等等,您的程序应定义<stdio.h>函数(签名main或{{1} }})。在托管实现中,大多数函数都是从int main(int, char**)间接调用的。作为John Zwinck answered,一些编译器为您提供了一种方法,以特定于实现的方式(和顺序)定义在int main(void)之前调用的函数。请注意,main通常需要进行一些特定于实现的初始化,而main实际上是以crt0为特定实现方式调用的。
  • 独立实现(对代码系统内核软件或微控制器上的嵌入式软件很有用)不提供完整的libc,也不定义代码的运行方式(并开始)。在这种情况下,您的实现应该定义软件的运行方式。实际上,您需要一些外部(例如汇编)代码来调用代码中的函数。

GCC编译器接受main标志为您提供独立实现(否则它被托管)

请注意,允许托管实现以棘手和神奇的方式编译某些标准函数(如果libc定义它们的标准头)。请参阅示例here

另请注意,该标准定义了-ffreestanding在托管实现中的工作方式({em>§5.1.2.2。托管环境 #include的第12页)。特别是main是缺少n1570main相同的唯一函数(标准exit(3)函数也会终止程序,就像从{{返回}一样1}})。

在实践中,您的问题是特定于实施的。