GCC错误“<变量>导致节类型冲突“ [英] GCC error "<variable> causes a section type conflict"
问题描述
问题为什么当试图将两个(RAM)变量(它们只是初始化值不同)发生编译器错误时, h3>
C源代码:
int __attribute __((section(。in_my_data )))_foo = 1;
int __attribute __((section(。in_my_data)))_bar = 0; (相关)GCC编译器输出:
mcve / main.c:75:45:error:_bar会导致节类型冲突
链接器脚本在 SECTIONS
定义中包含以下行,但(致命)错误来自编译器,而不是链接器。 p>
.my_data:{*(。in_my_data)}>数据
更多信息
更改C允许编译器使用两个部分的源允许编译通过,但如果两个输入部分映射到同一个输出部分,则链接器会生成一个错误。
C源代码:
int __attribute __((section(。in_my_data_nonzero)))_foo = 1;
int __attribute __((section(。in_my_data_zero)))_bar = 0;
链接器脚本:
.my_data:{*(。in_my_data *)}>数据
(相关)链接器输出:
链接错误:输入节'.in_my_data_nonzero'的属性与输出节'.my_data'冲突
交换C源代码行的顺序只会改变哪一部分(出现在C源代码中的那一部分)出错。
问题
GCC编译器要求一个段的变量初始化为零,而不是一个这是初始化为非零,反之亦然?
编译器是否尝试将变量初始化为零置于 .bss中
部分,而不是初始化数据的 .data
部分?还是有另一部分数据被初始化为零?
相关问题
在内存类型(ROM与RAM)之间存在冲突:
- 区段类型冲突嵌入手臂,它是什么?
- 如何解决部分类型冲突编译错误和使用gcc使用section属性的最佳实践
部分类型冲突使用M2tklib和glcd
...或将初始化 const
NOLOAD输出部分中的数据:
...或者仍然是原因的谜,可能是相关:
以上所有内容似乎都没有可以应用于此问题的答案,只要我可以告诉。
解决方案 警告:此答案可能只适用于Microchip XC16编译器。
研究
编译器将属性赋值给C变量,以便将它们分配给特定部分,如下所示(请参见< 注意下面的XC16特定信息1 code> - 分配给 .data
。
int b = 0;
- 分配给 .bss
。
int c;
- 分配给 .bss
。
ul>
第一个和最后一个有意义: .data
用于初始化数据,。 bss
用于未初始化的数据。但是,通过ANSI C启动( Note 2 ), .bss
数据也被设置为零。
Answer
看起来编译器包含 初始化的变量,但其值等于 .bss
部分中的所有第0位以及所有未初始化的部分。
根据 wikipedia :
实现还可以将静态分配的变量和常量初始化为一个仅包含零值位的值到BSS段。
解决方法
GCC有一个选项 -fno-zero-initialized-in-bss
用于将所有初始化为0的变量强制到 .data
部分中,如这回答呃。这可以应用在每个源文件的基础上,但不适用于单个变量。
如意算盘
如果有一个 __属性__((** doload **))
可以用来强制编译器将一个零初始化变量放在 .data
而不是 .bss
。
注意
注意1:XC16编译器可以使用 .ndata
和 .nbss $ c注意2:使用 __属性__((noload)标记一个变量<$ c $>以指示接近地址0x8000以下的数据。 ))
会导致变量被排除在 .bss
部分之外。 XC16生成一个特定的输出部分,每个变量都标有一个(GUID?)唯一名称。
Why is there a compiler error when attempting to place two (RAM) variables, which only differ by their initialisation values, into the same section?
Problem
The C source:
int __attribute__((section(".in_my_data"))) _foo = 1;
int __attribute__((section(".in_my_data"))) _bar = 0;
The (relevant) GCC compiler output:
mcve/main.c:75:45: error: _bar causes a section type conflict
The linker script contains the following line in the SECTIONS
definition, but the (fatal) error is from the compiler, not the linker.
.my_data : { *(.in_my_data) } > data
Further Information
Changing the C source to permit the compiler to use two sections allows the compile to pass, but the linker then generates an error if the two input sections are mapped into the same output section.
The C source:
int __attribute__((section(".in_my_data_nonzero"))) _foo = 1;
int __attribute__((section(".in_my_data_zero"))) _bar = 0;
The linker script:
.my_data : { *(.in_my_data*) } > data
The (relevant) linker output:
Link Error: attributes for input section '.in_my_data_nonzero' conflict
with output section '.my_data'
Swapping the order of the lines in the C source only changes which section (the second to appear in the C source) is in error.
Question
What attribute(s) does the GCC compiler require of a section for a variable that is initialised with zero that it doesn't for one that is initialised with non-zero, or vice versa?
Is the compiler trying to place the variables that are initialised to zero in the .bss
section, rather than the .data
section for initialised data? Or is there another section for data that is initialised to zero?
Related questions
Similar questions appear cover issues with conflicts between memory types (ROM vs. RAM):
- "Section type conflict" in arm embedded, what is it?
- How do I resolve a "section type conflict" compile error and best practices for using section attribute with gcc
- Getting a "section type conflict" using M2tklib and glcd
... or putting initialised const
data in NOLOAD output sections:
... or remain a mystery as to the cause and may be related:
None of the above appear to have an answer that I can apply to issue in this question, as far as I can tell.
解决方案 Caveat: This answer may only apply to the Microchip XC16 compiler.
Research
The compiler assigns attributes to C variables so that they are allocated to specific sections as follows (see Note 1 below for XC16 specific information).
int a = 1;
- is assigned to .data
.
int b = 0;
- is assigned to .bss
.
int c;
- is assigned to .bss
.
The first and last of these make sense: .data
is used for initialised data and .bss
is used for uninitialised data. However, .bss
data is also set to zero by the ANSI C start up (see Note 2).
Answer
It would appear that the compiler is including variables that are initialised, but with a value that equates to all bits 0 in the .bss
section as well as all those which are not initialised at all.
According to wikipedia:
An implementation may also assign statically-allocated variables and constants initialized with a value consisting solely of zero-valued bits to the BSS section.
Workaround
GCC has an option -fno-zero-initialized-in-bss
which can be used to force all variables that are initialised with zero into the .data
section, as stated in this answer. This can be applied on a per-source file basis, but not on individual variables.
Wishful Thinking
It would be nice if there were an __attribute__((**doload**))
that could be applied to force the compiler to place a zero-initialised variable in .data
instead of .bss
.
Notes
Note 1: The XC16 compiler may use .ndata
and .nbss
to indicate near data below address 0x8000.
Note 2: Marking a variable with __attribute__((noload))
will result in the variable being excluded from the .bss
section. XC16 generates a specific output section, with a (GUID?) unique name for each variable marked as such.
这篇关于GCC错误“<变量>导致节类型冲突“的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!