LTO 和 --gc-sections 为什么可能把注册表或中断表裁掉?
按段回收只保留从链接根可达的 Section,LTO 还会跨翻译单元分析。仅靠自定义段或看似未引用的注册对象可能被删除,需要在链接脚本用 KEEP、建立显式引用,并理解 used/retain 属性的工具链语义。
Question Bank
按知识、方向与难度筛选;每道题都有分层回答和工程追问。
按段回收只保留从链接根可达的 Section,LTO 还会跨翻译单元分析。仅靠自定义段或看似未引用的注册对象可能被删除,需要在链接脚本用 KEEP、建立显式引用,并理解 used/retain 属性的工具链语义。
restrict 是特定执行期间对对象访问路径的别名承诺,可帮助向量化和消除重复加载。若调用者传入重叠对象却违反承诺,行为未定义;它不是运行时检查,也不等于 const。
优化器可假设不兼容类型的指针通常不会指向同一对象;违反有效类型和别名规则后,读写可能被重排、缓存或删除。字节观察可通过 character type,位级转换优先用 memcpy,而不是随意强转指针。
枚举的兼容整数类型和大小受语言规则、取值范围及实现选项影响,ABI 或编译参数变化可能改变布局。协议和 Flash 格式应使用明确宽度整数,并显式校验值是否属于合法枚举集合。
先保留可复现构建与符号,比较编译参数、链接脚本和内存布局;优先查未初始化变量、越界、数据竞争、未定义行为、时序变化及缺失 volatile/屏障,而不是直接永久关闭优化。
对齐要求决定对象合法起始地址,编译器会在成员之间和结构体尾部插入填充。某些内核能处理非对齐访问但性能下降,另一些会直接产生总线异常;协议数据应逐字段解码或复制到已对齐对象。
回调通常应与 void *context、调用上下文约定和所有权规则一起注册。注销要防止回调正在执行,可用引用计数、同步屏障或事件循环串行化;绝不能保存已经失效的栈地址。
可重入强调函数尚未返回时再次进入仍正确,通常不能依赖未保护的共享可变状态;线程安全可借助锁实现,但持锁函数未必可重入;中断安全还要求调用上下文、阻塞和时延都符合 ISR 约束。