声明为“const”的全局初始化变量转到文本段,而那些声明为“静态”的则转到文本段。转到数据段。为什么?

发布于 2024-09-27 16:06:08 字数 784 浏览 8 评论 0原文

#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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

A君 2024-10-04 16:06:08

你很困惑。 conststatic 之间没有二分法;两者是独立的。假设所有数据都已初始化,static const 和外部(全局)const 都将进入 text,并且都将进入非 const code> 限定的 static 和非 const 限定的外部将进入 data

至于bss,像ELF这样的现代二进制格式实际上对于常量和非常量零数据有单独的bsssize 命令的输出只是不显示它。

You're confused. There is no dichotomy between const and static; the two are independent. Assuming all data is initialized, both static const and external (global) const will go in text and both non-const-qualified static and non-const-qualified external will go in data.

As for bss, modern binary formats like ELF actually have separate bss for constant and nonconstant zero data. The output of the size command just doesn't show it.

指尖微凉心微凉 2024-10-04 16:06:08

来自Kernighan &里奇:

static 是存储类说明符。
其他存储类说明符有:
自动、寄存器、外部和类型定义。这
static 说明符给出声明的
对象静态存储类。应用于外部变量或函数的静态声明将该对象的范围限制为正在编译的源文件的其余部分。静止的
对象可能是块本地的或
所有块的外部,但在任一块中
case 在退出时保留其值
从函数和重入函数以及
块。

然而,

const 是类型限定符。另一个
类型限定符是不稳定的。这
const 的目的是宣布
可以放置的物体
只读存储器,也许
增加机会
优化。

我想人们可以推断这两个关键字都有不同的用途;位于文本/代码段中的const变量从其用途来看是非常清楚的。

From Kernighan & Ritchie:

static is a storage class specifier.
Other storage class specifiers are:
auto, register, extern & typedef. The
static specifier gives the declared
objects static storage class. The static declaration, applied to an external variable or function, limits the scope of that object to the rest of the source file being compiled. Static
objects may be local to a block or
external to all blocks, but in either
case retain their values across exit
from and reentry to functions and
blocks.

Whereas,

const is a type qualifier. The other
type qualifier is volatile. The
purpose of const is to announce
objects that may be placed in
read-only memory, and perhaps to
increase opportunities for
optimization.

I suppose one can infer that both these keywords serve distinct purposes; that of const variables being in text/code segment is quite clear from its purpose.

柠北森屋 2024-10-04 16:06:08

让内存保护发挥作用。任何写入 const 的尝试都会触发段错误。

To allow memory protection to work. Any attempt to write to a const will trigger a segfault.

狼性发作 2024-10-04 16:06:08

当您声明变量 const 时,您就是在告诉编译器您绝不会更改其值。另一方面,通过在文件范围内进行静态声明,您可以告诉编译器该变量对于声明它的编译单元来说是私有的,但该编译单元中的函数是私有的。仍然允许修改这个变量。

正如奥利在他的 答案,在text段中定位const变量可以让系统强制执行内存访问保护。另外,考虑嵌入式系统,在这种情况下,text 段通常写入闪存,因此不可修改。 databss 段等位于 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 the static 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 the text segment allows the system to enforce memory access protection. Also, consider an embedded system, in that case the text segment is usually written to flash and is thus non-modifiable. The data, bss segments etc. are located in RAM and their modification is allowed.

懷念過去 2024-10-04 16:06:08

通过将 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文