TASKING编译器自动数组初始化的内存分配差异问询
TASKING编译器函数内自动数组的内存分配差异原因
两种代码变体的编译器处理逻辑
变体1:带显式初始化列表的自动数组
#define ARRAY_LENGTH (3u) void my_func(void) { /* VARIANT 1: Initialisation of array */ float my_array[ARRAY_LENGTH] = {1.f,2.f,3.f}; ... return; }
当用显式初始化列表声明自动局部数组时,TASKING编译器会把初始化用到的常量值(1.f、2.f、3.f)作为初始化模板,存储在数据内存的可读写/只读数据段中。函数调用时,编译器生成的代码会将这个模板里的值一次性拷贝到栈上为my_array分配的空间,因此你能在.map文件中看到该初始化模板的内存分配记录。
变体2:先声明后赋值的自动数组
#define ARRAY_LENGTH (3u) void my_func(void) { /* VARIANT 2: array is not initialized */ float my_array[ARRAY_LENGTH]; /* VARIANT 2: values are assigned later in the code */ my_array[0] = 1.f; my_array[1] = 2.f; my_array[2] = 3.f; ... return; }
这种场景下,数组没有编译期确定的初始化值,编译器会直接在栈上为my_array预留对应大小的空间,运行时通过独立赋值语句直接把数值写入栈内存,不需要在数据段预存任何初始化模板,因此.map文件中不会出现相关分配记录。
底层优化逻辑
这是TASKING针对嵌入式资源受限场景的针对性优化:
- 对有确定初始化值的小自动数组,预存初始化模板能减少运行时指令量(批量拷贝替代多次单个赋值),提升执行效率;
- 对动态赋值的数组,直接栈分配可避免占用宝贵的数据段空间,契合嵌入式系统内存资源节约的需求。
内容的提问来源于stack exchange,提问作者Alex Arpenteur
相关产品推荐
相关产品推荐

