将main重新定义为另一个名称

时间:2018-02-20 06:15:16

标签: c main c89

在C90中,我可以重新定义main并为其指定其他名称,并可能使用#define添加额外参数吗? 在头文件中有这个例子:

#include <stdio.h>
#include <stdlib.h>
#define main( void ) new_main( void )

int new_main( void );

标题在编译时不会显示任何错误。 但是,当我尝试使用主C文件进行编译时,我不断收到错误

In function '_start': Undefined reference to 'main'     

4 个答案:

答案 0 :(得分:2)

不,你不能这样做,因为它会违反语言和操作系统标准。名称main及其参数argcargvenviron构成系统加载程序调用约定的一部分。

随之而来的是简单的解释(没有ABI级别,只是API级别)。当您的程序已加载到内存中并即将启动时,加载程序需要知道要将哪个函数作为入口点调用,以及如何将其环境传递给它。如果可以更改main和/或其参数列表的名称,则需要将新调用接口的详细信息传递回加载器。并且没有方便的方法(除了编写自己的可执行加载器之外)。

In function '_start': Undefined reference to 'main'

在这里您可以看到Linux / POISX ELF加载器接口的实现细节。编译器在后台为您的程序添加函数_start,这是一个实际的程序入口点。 _start的任务是为大多数使用LibC的程序执行额外的初始化步骤。后来调用_start main_start。从理论上讲,你可以编写一个程序,它有自己的函数main而不是_start,它会很好。这不是微不足道的,因为您必须确保默认的_start代码不再附加到您的程序(没有双重定义),但它是可行的。不,出于同样的原因,您不能选择server以外的其他名称。

答案 1 :(得分:0)

编译单元中#define main new_main的存在不会影响实现在程序启动时调用的函数的名称。无论您定义任何宏,该实现都将调用名为main的函数。

如果您要使用#define这样的main()来阻止main()的主要声明以该名称生成函数,则需要包含exit()的定义别的地方;然后,备用版本可以调用原始版本。例如,如果原始定义没有使用其参数,并且如果程序仅通过从main()返回[而不是使用#define main new_main]退出,则可能会将main放在使用的头文件中通过#include <stdio.h> #include <conio.h> // For getch() function. int main(void) { int result = main(); printf("\nExit code was %d. Strike any key.\n", result); getch(); return result; } 的主要定义,然后在另一个文件中执行类似的操作:

main

在大多数情况下,最好在普通的“main”函数中添加任何此类代码,但这种方法在包含get_text的文件由每个构建的代码生成工具生成的情况下非常有用。 ,或由于某些其他原因无法修改以包含此类代码。

答案 2 :(得分:0)

不,你不能(正如格里戈里所说)。

但是,您可以立即致电您的代理主管

int
your_new_main(int argc, char* argv[], char* envp[]) {
    ... //your stuff goes here
}

//just place this in an include file, and only include in main...
int
main( int argc, char* argv[], char* envp[])
{
    int result = your_new_main(argc, argv);
    return result;
}

至于是否支持envp?

答案 3 :(得分:0)

假设您正在使用gcc-nostdlib传递给您的程序,然后设置一个新条目,方法是将其传递给gcc,并将其传递给链接器{{1} }。执行此操作不会让您在调用main之前访问C运行时所执行的任何优秀功能,而您必须自己执行此操作。

您可以查看有关在调用-Wl,-enew_main之前发生的事情的资源。

What Happens Before main