关于 $ Super $ $ 和 $ Sub $ $ 的用法

这个符号想必不少人也是在RT-Thread的KEIL MDK工程源码中接触到的,我也一样。
文章中我给$这个符号间加了很多空格为了防止跟文字的语法冲突了,需留意一下,实际使用没有空格

官方note:
在这里插入图片描述

Keil帮助手册:
在这里插入图片描述
随便找了块STM32板子在MDK工程模板上测试这个符号的用法:

void $Sub$$main(void)
{
//  extern int main(void);
	extern int $Super$$main(void);
	//初始化HAL
	HAL_Init();
	//初始化系统时钟
	SystemClock_Config();
	delay_init(80); 		//初始化延时函数    80M系统时钟
	uart_init(115200);		//初始化串口,波特率为115200
	printf("初始化已完成\n");
	
	//回到真正的main函数里
	$Super$$main();
}

int main(void)
{
    u8 len;
    u16 times = 0;

//    HAL_Init();
//    SystemClock_Config();	//初始化系统时钟为80M
//    delay_init(80); 		//初始化延时函数    80M系统时钟
//    uart_init(115200);	//初始化串口,波特率为115200
	printf("main()\r\n");

    while(1)
    {
	}

运行效果:
在这里插入图片描述

通俗一点讲,实际上就相当于在main函数之前先运行了$ Sub $ $ main这个函数,并且在$ Sub $ $ main这个函数里最后一句$ Super $ $ main();又用真正的main函数整体替换这个$ Super $ $main(), $ Sub $ $ main最后成为了真的main函数(类似宏定义)。这种方法就是用于表面上看简化了main函数的程序复杂度,但本质上没有啥区别。

以上使用注意点:

  1. void $ Sub$$main(void)和int main(void)可以不放在同一个C文件中,就算放在同一文件中也没有先后顺序之分;
  2. extern int $ Super $ $ main(void);必须要有,且放在 $ Super $ $ main();调用之前,可以放在$ Sub $ $main函数里也可以放在外面。
  3. $ Super $ 和 和 Sub $ $基本是要成对使用
  4. 需要特定编译器才支持该符号,比如MDK
  5. $ Super $ 和 和 Sub $ $不只用于main函数,也可以用于其他任意函数。举例如下:
extern int $Super$$Fun(void);
void $Sub$$Fun(void)
{
    printf("在Fun函数之前调用$Sub$$Fun\n");
    $Super$$Fun();
    printf("fun2\r\n");
}

void Fun(void)
{
    printf("执行Fun\r\n");
}

void $Sub$$main(void)
{
//  extern int main(void);
	extern int $Super$$main(void);
	//初始化HAL
	HAL_Init();
	//初始化系统时钟
	SystemClock_Config();
	delay_init(80); 		//初始化延时函数    80M系统时钟
	uart_init(115200);		//初始化串口,波特率为115200
	printf("初始化已完成\n");
	
	//回到真正的main函数里
	$Super$$main();
}

int main(void)
{
    u8 len;
    u16 times = 0;

//    HAL_Init();
//    SystemClock_Config();	//初始化系统时钟为80M
//    delay_init(80); 		//初始化延时函数    80M系统时钟
//    uart_init(115200);	//初始化串口,波特率为115200
	printf("main()\r\n");
	Fun();
    while(1)
    {
	}

执行结果;
在这里插入图片描述
接上:
6. $ Super$$Fun();之后还可以写代码且能够执行,因为这里相当于整体把Fun函数替换进来,执行完Fun()后接着往下执行,相当于 $ Sub $ $Fun()变成了真正的Fun()。
7. extern int main(void);这句好像没有什么必要。
8. 可以用于给某个函数打补丁而不破坏原来的程序结构
9. 暂时就这么多了