首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >GCC错误"<variable>导致区段类型冲突“

GCC错误"<variable>导致区段类型冲突“
EN

Stack Overflow用户
提问于 2015-05-06 12:37:06
回答 2查看 11.4K关注 0票数 7

为什么在尝试将两个(RAM)变量(它们的初始化值不同)放入同一个部分时会出现编译器错误?

问题

C消息来源:

代码语言:javascript
运行
复制
int __attribute__((section(".in_my_data"))) _foo = 1;
int __attribute__((section(".in_my_data"))) _bar = 0;

(相关) GCC编译器输出:

代码语言:javascript
运行
复制
mcve/main.c:75:45: error: _bar causes a section type conflict

链接器脚本在SECTIONS定义中包含以下行,但(致命的)错误来自编译器,而不是链接器。

代码语言:javascript
运行
复制
.my_data : { *(.in_my_data) } > data

更多信息

更改C源以允许编译器使用两个节允许编译传递,但是如果将两个输入部分映射到相同的输出部分,则链接器将生成一个错误。

C消息来源:

代码语言:javascript
运行
复制
int __attribute__((section(".in_my_data_nonzero"))) _foo = 1;
int __attribute__((section(".in_my_data_zero"))) _bar = 0;

链接器脚本:

代码语言:javascript
运行
复制
.my_data : { *(.in_my_data*) } > data

(相关的)链接器输出:

代码语言:javascript
运行
复制
Link Error: attributes for input section '.in_my_data_nonzero' conflict
with output section '.my_data'

交换C源中行的顺序只会更改哪个部分(出现在C源中的第二个部分)出现错误。

问题

GCC编译器对以零初始化的变量的节要求什么属性,而对于非零初始化变量则不需要,反之亦然?

编译器是否试图将初始化为零的变量放置在.bss部分中,而不是将初始化数据的.data部分放置在其中?或者,是否有另一段数据被初始化为零?

相关问题

类似的问题涉及内存类型之间的冲突(ROM与RAM):

..。或者将初始化的const数据放在NOLOAD输出部分:

..。或对其原因仍是一个谜,并可能与此有关:

就我所知,上述任何一项似乎都没有我可以申请的答案。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-05-06 16:00:49

警告:这个答案可能只适用于微芯片XC16编译器。

研究

编译器将属性分配给C变量,以便将它们分配给特定的部分,如下所示(有关XC16特定信息,请参阅下面的注1)。

  • int a = 1; -被分配给.data
  • int b = 0; -被分配给.bss
  • int c; -被分配给.bss

其中第一个也是最后一个有意义:.data用于初始化数据,.bss用于未初始化的数据。但是,ANSI启动也将.bss数据设置为零(参见注2)。

回答

编译器似乎包含了初始化的变量,但其值等于.bss部分中的所有位0,以及所有未初始化的变量。

根据维基百科

实现还可以将静态分配的变量和常数分配给BSS部分,这些变量和常量初始化时仅由零值比特组成。

解决办法

GCC有一个选项-fno-zero-initialized-in-bss,它可以强制所有以零初始化的变量进入.data部分,如这个答案中所述。这可以在每个源文件的基础上应用,但不能应用于单个变量。

一厢情愿

如果有一个__attribute__((**doload**))可以用来强制编译器在.data而不是.bss中放置一个零初始化变量,那就太好了。

备注

注1: XC16编译器可以使用.ndata.nbss来指示地址0x8000以下的接近数据。

注2:用__attribute__((noload))标记变量将导致变量被排除在.bss部分之外。XC16生成一个特定的输出部分(GUID?)标记为这样的每个变量的唯一名称。

票数 7
EN

Stack Overflow用户

发布于 2015-10-16 11:41:02

默认情况下,GCC将对象类放置在不同的部分,可执行代码转到.text,初始化数据到.data,静态数据放到.bss,还有一些更模糊的数据。

如果你试图强迫两个不同类别的对象属于同一部分,GCC将引起这个部分的错误。

解决方案是将它们放置在不同的部分,最后,告诉链接器最终将这些对象合并到同一节中,例如:

代码语言:javascript
运行
复制
.boot : {                 // target ELF section will contain....
    *(.boot)              // executable code
    *(.boot_rodata)       // constant data
    *(.boot_bss)          // static data
} > BOOT                  // to finally be place in this area
票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30076949

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档