为何C语言int类型内联数组开启编译优化后输出值不符预期?
结论判定
这是C语言标准明确界定的未定义行为,并非编译器存在Bug。
问题本质
你在else分支内定义的uint32_t indices[] = { queue_num1, queue_num2 };是存储在栈上的局部自动数组,它的有效生命周期仅覆盖所属的else代码块:
当代码执行完else块的收尾逻辑时,indices数组占用的栈空间会被立即回收,变成不可合法访问的无效地址。你将这个失效的栈地址赋值给info.nums指针,后续print_queue通过这个指针读取内存的操作,完全属于未定义行为,不存在任何可被保证的运行结果。
不同编译场景的表现差异解释
- 无优化编译时,编译器不会主动调整栈布局、也不会主动擦除已回收栈区域的原有数据,原
indices对应的栈位置暂时没有被其他逻辑覆盖,因此能偶然读到之前存储的4、5数值,这完全是巧合,不代表代码逻辑正确 - 开启优化选项后,编译器会根据优化规则重新规划栈空间:要么主动将已回收的栈位置清零,要么把这部分内存分配给其他临时变量使用,你读到的0值、甚至随机的内存残留垃圾值,都是未定义行为下的正常表现——未定义行为的运行结果没有任何可预测性,出现什么值都不奇怪
可行修复方案
如果需要让info.nums指向的内存始终合法可访问,可根据实际场景选择对应实现:
- 将数组改为静态存储类型,延长生命周期,比如定义为
static uint32_t indices[] = { queue_num1, queue_num2 }; - 通过堆动态申请内存存储这两个值,在使用完成后手动释放对应内存
内容的提问来源于stack exchange,提问作者Keidax
相关产品推荐
相关产品推荐

