声明为“const”的全局初始化变量转到文本段,而那些声明为“静态”的则转到文本段。转到数据段。为什么?
#include <stdio.h>
const int str[1000] = {0};
int main(void)
{
printf("arr is %d\n", str[0]);
return 0;
}
具有以下输出:
[-exercises/adam/stack2]:size a.out
text data bss dec hex filename
5133 272 24 5429 1535 a.out
而:
#include <stdio.h>
static int str[1000] = {0};
int main(void)
{
printf("arr is %d\n", str[0]);
return 0;
}
具有以下输出:
[-exercises/adam/stack2]:size a.out
text data bss dec hex filename
1080 4292 24 5396 1514 a.out
当数组未初始化时,它再次转到“const”的文本段和“static”的 BSS。
该变量是全局的,应该可以从它所属的可执行文件中的任何位置访问(因为没有“静态”),但鉴于它是一个变量,我不知道为什么它被放置在文本段而不是数据段中?
#include <stdio.h>
const int str[1000] = {0};
int main(void)
{
printf("arr is %d\n", str[0]);
return 0;
}
Has the following output:
[-exercises/adam/stack2]:size a.out
text data bss dec hex filename
5133 272 24 5429 1535 a.out
Whereas:
#include <stdio.h>
static int str[1000] = {0};
int main(void)
{
printf("arr is %d\n", str[0]);
return 0;
}
Has the following output:
[-exercises/adam/stack2]:size a.out
text data bss dec hex filename
1080 4292 24 5396 1514 a.out
When the array is uninitialized -- it again goes to text segment for "const" and to BSS for "static".
The variable is global and should be accessible from anywhere in the executable it is part of (because of no "static"), but given its a variable I don't know why it is placed in text segment instead of data segment?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
你很困惑。
const
和static
之间没有二分法;两者是独立的。假设所有数据都已初始化,static const
和外部(全局)const
都将进入text
,并且都将进入非const
code> 限定的static
和非const
限定的外部将进入data
。至于
bss
,像ELF这样的现代二进制格式实际上对于常量和非常量零数据有单独的bss
。size
命令的输出只是不显示它。You're confused. There is no dichotomy between
const
andstatic
; the two are independent. Assuming all data is initialized, bothstatic const
and external (global)const
will go intext
and both non-const
-qualifiedstatic
and non-const
-qualified external will go indata
.As for
bss
, modern binary formats like ELF actually have separatebss
for constant and nonconstant zero data. The output of thesize
command just doesn't show it.来自Kernighan &里奇:
然而,
我想人们可以推断这两个关键字都有不同的用途;位于
文本/代码段
中的const
变量从其用途来看是非常清楚的。From Kernighan & Ritchie:
Whereas,
I suppose one can infer that both these keywords serve distinct purposes; that of
const
variables being intext/code segment
is quite clear from its purpose.让内存保护发挥作用。任何写入 const 的尝试都会触发段错误。
To allow memory protection to work. Any attempt to write to a const will trigger a segfault.
当您声明变量
const
时,您就是在告诉编译器您绝不会更改其值。另一方面,通过在文件范围内进行静态声明,您可以告诉编译器该变量对于声明它的编译单元来说是私有的,但该编译单元中的函数是私有的。仍然允许修改这个变量。正如奥利在他的 答案,在
text
段中定位const
变量可以让系统强制执行内存访问保护。另外,考虑嵌入式系统,在这种情况下,text
段通常写入闪存,因此不可修改。data
、bss
段等位于 RAM 中,并且允许对其进行修改。When you declare a variable
const
you're telling the compiler that you never intend to change its value. On the other hand, with thestatic
declaration made at the file scope, you're telling the compiler that that variable is private to the compilation unit it has been declared in, but functions within that compilation unit are still allowed to modify this variable.As Oli mentions in his answer, locating the
const
variable in thetext
segment allows the system to enforce memory access protection. Also, consider an embedded system, in that case thetext
segment is usually written to flash and is thus non-modifiable. Thedata
,bss
segments etc. are located in RAM and their modification is allowed.通过将 const 数据放入文本部分,编译器试图强制执行 constness。
请记住,TEXT 部分会加载到 MMU 页表中标记为只读的内存页中。这是为了防止代码意外损坏。通过将 const 数据放入同一区域,也可以使该数据只读。对此数据的任何写入都会引发异常。
声明为静态的未初始化数据将进入 BSS 段以节省可执行文件中的空间。该区域由加载器在内存中分配。声明为静态的初始化数据将进入 DATA 段,该段是可读写的。
By putting the const data into the text section, the compiler is trying to enforce constness.
Keep in mind that the TEXT section is loaded into memory pages marked read only in the MMU page tables. This is to guard against accidental corruption of code. By putting const data in the same area, makes that data read only as well. Any writes to this data will then invoke exceptions.
Uninitialized data declared static will go into BSS segment to conserve space in the executable file. This area is allocated in memory by the loader. Initialized data declared static will go into the DATA segment, which is read-write.