在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'
答案 0 :(得分:2)
不,你不能这样做,因为它会违反语言和操作系统标准。名称main
及其参数argc
,argv
和environ
构成系统加载程序调用约定的一部分。
随之而来的是简单的解释(没有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
之前发生的事情的资源。