前言
在本篇文章当中主要给大家介绍C语言当中一些不常用的特性,比如在main函数之前和之后设置我们想要执行的函数,以及各种花式退出程序的方式。
main函数是最先执行和最后执行的函数吗?
C语言构造和析构函数
通常我们在写C程序的时候都是从main函数开始写,因此我们可能没人有关心过这个问题,事实上是main函数不是程序第一个执行的函数,也不是程序最后一个执行的函数。
#include <stdio.h> |
|
void __attribute__((constructor)) init1() {
|
|
printf("before main funciton\n"); |
|
} |
|
int main() {
|
|
printf("this is main funciton\n"); |
|
} |
我们编译上面的代码然后执行,输出结果如下图所示:
➜ code git:(main) ./init.out |
|
before main funciton |
|
this is main funciton |
由此可见main函数并不是第一个被执行的函数,那么程序第一次执行的函数是什么呢?很简单我们看一下程序的调用栈即可。
从上面的结果可以知道,程序第一个执行的函数是_start,这是在类Unix操作系统上执行的第一个函数。
那么main函数是程序执行的最后一个函数吗?我们看下面的代码:
#include <stdio.h> |
|
void __attribute__((destructor)) __exit() {
|
|
printf("this is exit\n"); |
|
} |
|
void __attribute__((constructor)) init() {
|
|
printf("this is init\n"); |
|
} |
|
int main() {
|
|
printf("this is main\n"); |
|
return 0; |
|
} |
上面程序的输出结果如下:
➜ code git:(main) ./out.out |
|
this is init |
|
this is main |
|
this is exit |
由此可见main函数也不是我们最后执行的函数!事实上我们除了上面的方法之外我们也可以在libc当中注册一些函数,让程序在main函数之后,退出执行前执行这些函数。
on_exit和atexit函数
我们可以使用上面两个函数进行函数的注册,让程序退出之前执行我们指定的函数
#include <stdio.h> |
|
#include <stdlib.h> |
|
void __attribute__((destructor)) __exit() {
|
|
printf("this is exit\n"); |
|
} |
|
void __attribute__((constructor)) init() {
|
|
printf("this is init\n"); |
|
} |
|
void on__exit() {
|
|
printf("this in on exit\n"); |
|
} |
|
void at__exit() {
|
|
printf("this in at exit\n"); |
|
} |
|
int main() {
|
|
on_exit(on__exit, NULL); |
|
atexit(at__exit); |
|
printf("this is main\n"); |
|
return 0; |
|
} |
this is init |
|
this is main |
|
this in at exit |
|
this in on exit |

本文探讨了C语言中一些不常见的程序退出方法,包括on_exit和atexit函数注册的执行、exit与_exit函数的区别以及如何通过内联汇编直接退出程序。文章强调了atexit函数的使用优先级,并指出_exit函数会直接终止程序,跳过注册的清理函数。

最低0.47元/天 解锁文章
3万+

被折叠的 条评论
为什么被折叠?



