#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”的文本段和“静态”的BSS。
变量是全局变量,应该可以从可执行文件中的任何位置访问(因为没有“静态”),但是如果它是变量,我不知道它为什么放在文本段而不是数据段中?
答案 0 :(得分:7)
来自 Kernighan&amp;里奇强>:
static是存储类说明符。 其他存储类说明符是: auto,register,extern&amp;的typedef。该 static specifier给出声明的 对象静态存储类。应用于外部变量或函数的静态声明将该对象的范围限制为正在编译的源文件的其余部分。静态的 对象可以是块的本地对象 所有街区外部,但在其中一个 案例在退出时保留其值 从和重新进入功能和 块。
然而,
const是一个类型限定符。另一个 type限定符是volatile。该 const的目的是宣布 可放入的物体 只读内存,也许是 增加机会 优化
我想可以推断这两个关键字都有不同的用途; const
中的text/code segment
个变量的目的非常明确。
答案 1 :(得分:6)
const
和static
之间没有二分法;两者是独立的。假设所有数据都已初始化,static const
和外部(全局)const
都会进入text
,而非const
- 合格static
和非{ {1}} - 符合条件的外部版本将进入const
。
对于data
,像ELF这样的现代二进制格式实际上对于常量和非常量零数据具有单独的bss
。 bss
命令的输出只是没有显示它。
答案 2 :(得分:3)
允许内存保护工作。任何写入const的尝试都会触发段错误。
答案 3 :(得分:1)
当你声明一个变量const
时,你告诉编译器你永远不打算改变它的值。另一方面,使用在文件范围内进行的static
声明,您告诉编译器该变量对于已声明的编译单元是私有的,但仍允许该编译单元中的函数修改此变量。
正如Oli在answer中提到的那样,在const
段中找到text
变量可以让系统强制执行内存访问保护。此外,考虑一个嵌入式系统,在这种情况下,text
段通常写入闪存,因此是不可修改的。 data
,bss
段等位于RAM中,允许修改。
答案 4 :(得分:1)
通过将const数据放入文本部分,编译器正在尝试强制执行const。
请记住,TEXT部分被加载到MMU页面表中标记为只读的内存页面中。这是为了防止代码意外损坏。通过将const数据放在同一区域中,也可以只读取该数据。然后,对此数据的任何写入都将调用异常。
声明为static的未初始化数据将进入BSS段以节省可执行文件中的空间。该区域由加载器分配在内存中。声明为static的初始化数据将进入DATA段,这是可读写的。