使用aarch64-none-elf-gcc编译时自定义节内结构体顺序反转问题
自定义节内符号顺序在x86与AArch64 GCC编译下反转的原因
核心原因是:GCC本身不保证同一自定义节中全局变量的排列顺序,最终顺序由目标平台的默认链接器脚本决定,x86和AArch64平台的链接器脚本对自定义节的处理逻辑存在差异。
具体细节:
- x86平台的默认链接器脚本,会将同一节内的符号按照代码中的声明顺序(也就是符号在目标文件中出现的顺序)排列,所以输出是
Test1→Test2→Test3。 - aarch64-none-elf-gcc对应的ARM链接器脚本,默认对同一节内的符号采用反向排序策略,或者说在合并节内容时从后往前处理符号,导致输出顺序变成
Test3→Test2→Test1。
需要注意的是,依赖自定义节内的符号顺序属于未定义行为——C语言标准和GCC文档都没有规定同一节内符号的排列顺序,不同编译器、不同平台甚至不同版本的链接器都可能有不同的行为。
如果需要稳定的遍历顺序,推荐两种可靠方案:
- 编写自定义链接器脚本,显式指定节内符号的排列顺序。
- 改用数组存储结构体指针,数组的元素顺序是编译时确定的,完全可控。示例代码:
typedef struct test_t { char *test_name; } test_t; test_t test1 = { "Test 1" }; test_t test2 = { "Test 2" }; test_t test3 = { "Test 3" }; test_t *test_list[] = { &test1, &test2, &test3 }; // 顺序固定 int main(int argc, char *argv[]) { for (size_t i = 0; i < sizeof(test_list)/sizeof(test_list[0]); i++) { printf("%s\n", test_list[i]->test_name); } return 0; }
内容的提问来源于stack exchange,提问作者elhadi dp ıpɐɥןǝ
相关产品推荐
相关产品推荐

