GCC中__attribute__((noinit))与__attribute__((section("\.noinit")))的差异问询
GCC中__attribute__((noinit))与__attribute__((section(".noinit")))的差异解析
核心作用差异
__attribute__((section(".noinit"))):本质是段归属控制,强制将变量放入链接脚本中定义的.noinit段。变量是否会被初始化,完全取决于链接脚本中.noinit段的配置——如果段标记了NOLOAD,则变量不会被初始化;如果没加NOLOAD,变量仍会被常规初始化(比如清零)。__attribute__((noinit)):直接向编译器声明不对该变量执行任何初始化操作,属性本身不强制指定段归属。不过在ARM平台的GCC实现中,这个属性默认会把变量放到.noinit段,但这是编译器的默认行为,并非属性的硬性规则。
你遇到的属性冲突问题解析
1. section(".mySection")与noinit共存的警告
当你同时使用这两个属性时,GCC会触发ignoring attribute 'noinit' because it conflicts with attribute 'section'警告,原因是:
ARM GCC中noinit默认关联.noinit段,而section(".mySection")显式指定了自定义段,两者的段指向冲突,编译器会优先遵循section的显式配置,因此忽略noinit属性。
2. 两次section属性的编译错误
uint32_t myVariable __attribute__((section(".noinit"), section(".mySection")));直接报错,是因为一个变量只能归属一个段,重复指定section属性违反了这个规则,编译器直接拒绝编译。
实现自定义未初始化段的正确方式
如果你想将变量放到自定义的mySection(已在链接脚本中标记为NOLOAD)且保证不初始化,只需要:
// 仅用section指定自定义段即可,链接脚本的NOLOAD已确保段不被初始化 uint32_t myVariable __attribute__((section(".mySection")));
链接脚本中mySection的NOLOAD标记会告诉加载器跳过该段的初始化,变量会保留上电后的原始值,无需额外添加noinit属性。
如果你的链接脚本还没给mySection加NOLOAD,必须先修改链接脚本,示例如下:
.mySection (NOLOAD) : { *(.mySection) } > RAM
内容的提问来源于stack exchange,提问作者bsheikh24
相关产品推荐
相关产品推荐

