c 语言 一定要有main 吗,语言律师-C程序是否需要main()?

语言律师-C程序是否需要main()?

标题说明了一切。 main()函数对于C程序是否绝对必要?

我之所以这样问是因为我正在查看Linux内核代码,但是没有看到main()函数。

elricL asked 2020-08-09T21:39:40Z

7个解决方案

63 votes

不,ISO C标准规定,仅在托管环境(例如具有基础操作系统的环境)中才需要5.1.2函数。

对于像嵌入式系统(或操作系统本身)这样的独立环境,它是由实现定义的。 从C99 5.1.2:

定义了两个执行环境:独立和托管。 在这两种情况下,当执行环境调用指定的C函数时,都会发生程序启动。

在独立的环境中(其中C程序的执行可能没有操作系统的任何好处),在程序启动时调用的函数的名称和类型是实现定义的。

关于Linux本身的启动方式,Linux内核的起始点是start_kernel,要获得整个引导过程的更完整描述,您应该从这里开始。

paxdiablo answered 2020-08-09T21:40:04Z

9 votes

main()函数由libc附带的目标文件调用。 由于内核不链接到libc,因此它具有自己的入口点,该入口点用汇编器编写。

Ignacio Vazquez-Abrams answered 2020-08-09T21:40:24Z

9 votes

好吧,不,但是...

C99指定在“程序启动时”在宿主环境中调用main(),但是,您不必使用C运行时支持。 您的操作系统执行映像文件,并在链接器提供的地址处启动程序。

如果您愿意编写符合操作系统要求而不是C99要求的程序,则可以不使用main()。 但是,系统越现代(复杂),使用C库(假设使用标准运行时启动)的麻烦就越大。

这是Linux的示例...

$ cat > nomain.S

.text

_start:

call iamnotmain

movl $0xfc, %eax

xorl %ebx, %ebx

int $0x80

.globl _start

$ cat > demo.c

void iamnotmain(void) {

static char s[] = "hello, world\n";

write(1, s, sizeof s);

}

$ as -o nomain.o nomain.S

$ cc -c demo.c

$ ld -static nomain.o demo.o -lc

$ ./a.out

hello, world

不过,现在可以说它不是“ C99程序”,而只是一个用C编写的对象模块的“ Linux程序”。

DigitalRoss answered 2020-08-09T21:41:02Z

3 votes

Paxdiablo的答案涵盖了您不会遇到主要问题的两种情况。 让我添加更多:

用于其他程序(例如,浏览器或文本编辑器等)的许多插件系统没有main()。

用C编写的Windows程序没有main()。(它们有WinMain()。)

JUST MY correct OPINION answered 2020-08-09T21:41:30Z

0 votes

操作系统加载程序必须调用单个入口点; 在GNU编译器中,入口点是在crt0.o链接的对象文件中定义的,其来源是汇编器文件crt0.s-在执行各种运行时启动任务(如建立命令)后调用main() 堆栈,静态初始化)。 因此,当构建链接默认crt0.o的可执行文件时,您必须具有main(),否则会出现链接器错误,因为在crt0.o中main()是未解决的符号。

修改crt0.s以调用其他入口点是可能的(如果有些不正当和不必要的话)。 只需确保针对项目创建了这样的目标文件,而不是修改默认版本,否则您将破坏该计算机上的每个版本。

操作系统本身具有自己的C运行时启动程序(将从引导加载程序中调用),因此可以调用所需的任何入口点。 我没有看过Linux的源代码,但可以想象它有自己的crt0.s,它将调用任何C代码入口点。

Clifford answered 2020-08-09T21:42:01Z

0 votes

main由glibc调用,它是应用程序(环3)的一部分,而不是内核(环0)的一部分。

该驱动程序有另一个入口点,例如基于WDM的Windows驱动程序是从DRIVERENTRY启动的

Sim Sun answered 2020-08-09T21:42:25Z

-2 votes

在机器语言中,事物按顺序执行,先执行的是先执行。 因此,默认值为编译器对您的main方法进行调用以符合C标准。

您的程序就像库一样,是已编译函数的集合。 库和标准可执行文件之间的主要区别在于,对于第二个库,编译器将生成汇编代码,该汇编代码将调用程序中的函数之一。

但是,您可以编写汇编代码来调用您的任意C程序函数(实际上与对库函数的调用相同),并且这与其他可执行文件也相同。 但是问题是,您不能在普通标准C中做到这一点,您必须求助于汇编甚至其他一些特定于编译器的技巧。

这只是一般性和肤浅的解释,我故意避免了一些技术差异,因为它们似乎无关紧要。

Trinidad answered 2020-08-09T21:42:59Z

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值