常数变量存储在C中的位置?

时间:2022-10-09 17:02:01

I wonder where constant variables are stored. Is it in the same memory area as global variables? Or is it on the stack?

我想知道常数变量存储在哪里。它和全局变量在同一个内存区域吗?还是在堆栈上?

12 个解决方案

#1


39  

How they are stored is an implementation detail (depends on the compiler).

如何存储它们是一个实现细节(取决于编译器)。

For example, in the GCC compiler, on most machines, read-only variables, constants, and jump tables are placed in the text section.

例如,在GCC编译器中,在大多数机器上,只读变量、常量和跳转表都放在文本部分。

#2


27  

Depending on the data segmentation that a particular processor follows, we have five segments:

根据特定处理器后面的数据分割,我们有五个部分:

  1. Code Segment - Stores only code, ROM
  2. 代码段-只存储代码,ROM
  3. BSS (or Block Started by Symbols) segment - Stores initialised global and static variables
  4. BSS(或由符号开始的块)段——存储初始化的全局变量和静态变量
  5. Stack segment - stores all the local varialbles and other informations regarding function return address etc
  6. 堆栈段——存储所有的本地变量和其他有关函数返回地址等信息
  7. Heap segment - all dynamic allocations happens here
  8. 堆段——所有的动态分配都发生在这里
  9. Data segment - stores uninitialised global and static variables
  10. 数据段——存储未初始化的全局变量和静态变量

Note that the difference between BSS and data segment is that the former store initialized global and static varialbes and the later stores UNinitialised ones.

注意,BSS和数据段之间的区别在于,前者存储初始化全局变量和静态变量,而后者存储未初始化变量。

Now, Why am I talking about the data segmentation when I must be just telling where are the constant variables stored... there's a reason to it...

现在,为什么我要讲的是数据分割当我必须告诉你常量变量存储在哪里…这是有原因的……

Every segment has a write protected region where all the constants are stored.

每个段都有一个写入保护区域,其中存储所有常量。

For example,

例如,

if I have a const int which is local variable, then it is stored in the write protected region of stack segment. and if I have a global that is initialised const var, then it is stored in BSS and if I have an uninitialised const var, then it is stored in data segment...

如果我有一个作为局部变量的const int,那么它就存储在堆栈段的写保护区域中。如果我有一个全局变量是初始化的const var,那么它存储在BSS中,如果我有一个未初始化的const var,那么它存储在数据段中……

To summarize, "const" is just a data QUALIFIER, which means that first the compiler has to decide which segment the variable has to be stored and then if the variable is a const, then it qualifies to be stored in the write protected region of that particular segment.

总而言之,“const”只是一个数据限定符,这意味着首先编译器必须决定要存储变量的哪个段,然后如果变量是const,那么它就被限定要存储在该特定段的写保护区域中。

I hope this would clarify most of the misunderstandings.... :-)

我希望这将澄清的大部分误解....:-)

Any further comments are welcome... :-)

欢迎进一步评论……:-)

#3


11  

Consider the code:

考虑一下代码:

const int i = 0;
static const int k = 99;

int function(void)
{
    const int j = 37;
    totherfunc(&j);
    totherfunc(&i);
  //totherfunc(&k);
    return(j+3);
}

Generally, i can be stored in the text segment (it's a read-only variable with a fixed value). If it is not in the text segment, it will be stored beside the global variables. Given that it is initialized to zero, it might be in the 'bss' section (where zeroed variables are usually allocated) or in the 'data' section (where initialized variables are usually allocated).

通常,我可以存储在文本段中(它是一个具有固定值的只读变量)。如果它不在文本段中,它将存储在全局变量旁边。在初始化为零的情况下,它可能位于“bss”部分(通常分配了zeroed变量),或者在“数据”部分(通常分配了初始变量)。

If the compiler is convinced the k is unused (which it could be since it is local to a single file), it might not appear in the object code at all. If the call to totherfunc() that references k was not commented out, then k would have to be allocated an address somewhere - it would likely be in the same segment as i.

如果编译器确信k是未使用的(可能是因为它是单个文件的本地文件),那么它可能根本不会出现在对象代码中。如果对totherfunc()的调用说引用k没有被注释掉,那么k就必须在某个地方分配一个地址——它可能与i在同一段中。

The constant (if it is a constant, is it still a variable?) j will most probably appear on the stack of a conventional C implementation. (If you were asking in the comp.std.c news group, someone would mention that the standard doesn't say that automatic variables appear on the stack; fortunately, SO isn't comp.std.c!)

常量(如果它是常量,它仍然是一个变量吗?)j很可能出现在常规C实现的堆栈上。(如果你在报纸上问的话。c新闻集团,有人会说标准没有说自动变量出现在堆栈上;幸运的是,所以不是comp.std.c !)

Note that I forced the variables to appear because I passed them by reference - presumably to a function expecting a pointer to a constant integer. If the addresses were never taken, then j and k could be optimized out of the code altogether. To remove i, the compiler would have to know all the source code for the entire program - it is accessible in other translation units (source files), and so cannot as readily be removed. Doubly not if the program indulges in dynamic loading of shared libraries - one of those libraries might rely on that global variable.

注意,我强制让变量出现,因为我通过引用传递它们——可能是传递给一个函数,该函数期望指针指向一个常量整数。如果地址从未被占用,那么j和k可以从代码中完全优化。要删除i,编译器必须知道整个程序的所有源代码——它可以在其他翻译单元(源文件)中访问,因此不能轻易删除。如果程序沉溺于共享库的动态加载,那么这种情况就更糟糕了——其中一个库可能依赖于这个全局变量。

(Stylistically - the variables i and j should have longer, more meaningful names; this is only an example!)

(风格上——变量i和j应该有更长的、更有意义的名称;这只是一个例子!

#4


3  

Depends on your compiler, your system capabilities, your configuration while compiling.

依赖于编译器、系统功能、编译时的配置。

gcc puts read-only constants on the .text section, unless instructed otherwise.

gcc将只读常量放在.text部分,除非另有指示。

#5


1  

Usually they are stored in read-only data section (while global variables' section has write permissions). So, trying to modify constant by taking its address may result in access violation aka segfault.

通常它们存储在只读数据部分(而全局变量部分具有写权限)。因此,试图通过获取其地址来修改常量可能会导致访问被称为segfault。

But it depends on your hardware, OS and compiler really.

但这取决于你的硬件、操作系统和编译器。

#6


1  

This is mostly an educated guess, but I'd say that constants are usually stored in the actual CPU instructions of your compiled program, as immediate data. So in other words, most instructions include space for the address to get data from, but if it's a constant, the space can hold the value itself.

这主要是一种有根据的猜测,但我想说常量通常作为即时数据存储在编译程序的实际CPU指令中。换句话说,大多数指令包括地址空间,以获取数据,但如果它是常数,空间就能保持值本身。

#7


1  

offcourse not , because

offcourse不会,因为

1) bss segment stored non inilized variables it obviously another type is there.

1)bss段存储非inilized变量,显然有另一种类型。

       (I) large static and global and non constants and non initilaized variables it stored .BSS section.

       (II) second thing small static and global variables and non constants and non initilaized variables stored in .SBSS section this included in .BSS segment.

2) data segment is initlaized variables it has 3 types ,

2)数据段为内变量,有3种类型,

      (I) large static and global and initlaized and non constants variables its stord in .DATA section.
      (II) small static and global and non constant and initilaized variables its stord in .SDATA1 sectiion.
     (III) small static and global and  constant and initilaized OR non initilaized variables its stord in .SDATA2 sectiion.

i mention above small and large means depents upon complier for example small means < than 8 bytes and large means > than 8 bytes and equal values.

我前面提到过,大的和小的意味着依赖于编译器,例如,小的意味着小于8字节,大的意味着>大于8字节,并且值相等。

but my doubt is local constant are where it will stroe??????

但我的疑问是,局部常数会在哪里发生??????

#8


0  

Global and constant are two completely separated keywords. You can have one or the other, none or both.

全局和常量是两个完全分离的关键字。你可以有一个或另一个,没有或两者都有。

Where your variable, then, is stored in memory depends on the configuration. Read up a bit on the heap and the stack, that will give you some knowledge to ask more (and if I may, better and more specific) questions.

那么,存储在内存中的变量取决于配置。读一点堆和堆栈,这会给您一些知识来问更多的问题(如果可能的话,更好更具体)。

#9


0  

Some constants arfen't even stored.

有些常数甚至没有存储。

Consider the following code: int x = foo(); x *= 2;. Chances are that the compiler will turn the multiplication into x = x+x; as that reduces the need to load the number 2 from memory.

考虑以下代码:int x = foo();x * = 2,。编译器有可能把乘法运算变成x = x+x;这样就减少了从内存中加载数字2的需要。

#10


0  

It may not be stored at all.

它可能根本不会被存储。

Consider some code like this:

考虑以下代码:

#import<math.h>//import PI
double toRadian(int degree){
  return degree*PI*2/360.0;
}

This enables the programmer to gather the idea of what is going on, but the compiler can optimize away some of that, and most compilers do, by evaluating constant expressions at compile time, which means that the value PI may not be in the resulting program at all.

这使程序员能够收集正在发生的事情的想法,但是编译器可以通过在编译时计算常量表达式来优化其中的一部分,这意味着PI的值可能根本不在结果程序中。

#11


0  

Just as an an add on ,as you know that its during linking process the memory lay out of the final executable is decided .There is one more section called COMMON at which the common symbols from different input files are placed.This common section actually falls under the .bss section.

就像添加一样,您知道,在链接过程中,最终可执行文件的内存被决定了。这个公共部分实际上位于。bss部分之下。

#12


0  

It must be stored in Text segment as it is read-only variables. http://shirleyanengineer.blogspot.in/2017/05/memory-layout-of-process.html

它必须存储在文本段中,因为它是只读变量。http://shirleyanengineer.blogspot.in/2017/05/memory-layout-of-process.html

#1


39  

How they are stored is an implementation detail (depends on the compiler).

如何存储它们是一个实现细节(取决于编译器)。

For example, in the GCC compiler, on most machines, read-only variables, constants, and jump tables are placed in the text section.

例如,在GCC编译器中,在大多数机器上,只读变量、常量和跳转表都放在文本部分。

#2


27  

Depending on the data segmentation that a particular processor follows, we have five segments:

根据特定处理器后面的数据分割,我们有五个部分:

  1. Code Segment - Stores only code, ROM
  2. 代码段-只存储代码,ROM
  3. BSS (or Block Started by Symbols) segment - Stores initialised global and static variables
  4. BSS(或由符号开始的块)段——存储初始化的全局变量和静态变量
  5. Stack segment - stores all the local varialbles and other informations regarding function return address etc
  6. 堆栈段——存储所有的本地变量和其他有关函数返回地址等信息
  7. Heap segment - all dynamic allocations happens here
  8. 堆段——所有的动态分配都发生在这里
  9. Data segment - stores uninitialised global and static variables
  10. 数据段——存储未初始化的全局变量和静态变量

Note that the difference between BSS and data segment is that the former store initialized global and static varialbes and the later stores UNinitialised ones.

注意,BSS和数据段之间的区别在于,前者存储初始化全局变量和静态变量,而后者存储未初始化变量。

Now, Why am I talking about the data segmentation when I must be just telling where are the constant variables stored... there's a reason to it...

现在,为什么我要讲的是数据分割当我必须告诉你常量变量存储在哪里…这是有原因的……

Every segment has a write protected region where all the constants are stored.

每个段都有一个写入保护区域,其中存储所有常量。

For example,

例如,

if I have a const int which is local variable, then it is stored in the write protected region of stack segment. and if I have a global that is initialised const var, then it is stored in BSS and if I have an uninitialised const var, then it is stored in data segment...

如果我有一个作为局部变量的const int,那么它就存储在堆栈段的写保护区域中。如果我有一个全局变量是初始化的const var,那么它存储在BSS中,如果我有一个未初始化的const var,那么它存储在数据段中……

To summarize, "const" is just a data QUALIFIER, which means that first the compiler has to decide which segment the variable has to be stored and then if the variable is a const, then it qualifies to be stored in the write protected region of that particular segment.

总而言之,“const”只是一个数据限定符,这意味着首先编译器必须决定要存储变量的哪个段,然后如果变量是const,那么它就被限定要存储在该特定段的写保护区域中。

I hope this would clarify most of the misunderstandings.... :-)

我希望这将澄清的大部分误解....:-)

Any further comments are welcome... :-)

欢迎进一步评论……:-)

#3


11  

Consider the code:

考虑一下代码:

const int i = 0;
static const int k = 99;

int function(void)
{
    const int j = 37;
    totherfunc(&j);
    totherfunc(&i);
  //totherfunc(&k);
    return(j+3);
}

Generally, i can be stored in the text segment (it's a read-only variable with a fixed value). If it is not in the text segment, it will be stored beside the global variables. Given that it is initialized to zero, it might be in the 'bss' section (where zeroed variables are usually allocated) or in the 'data' section (where initialized variables are usually allocated).

通常,我可以存储在文本段中(它是一个具有固定值的只读变量)。如果它不在文本段中,它将存储在全局变量旁边。在初始化为零的情况下,它可能位于“bss”部分(通常分配了zeroed变量),或者在“数据”部分(通常分配了初始变量)。

If the compiler is convinced the k is unused (which it could be since it is local to a single file), it might not appear in the object code at all. If the call to totherfunc() that references k was not commented out, then k would have to be allocated an address somewhere - it would likely be in the same segment as i.

如果编译器确信k是未使用的(可能是因为它是单个文件的本地文件),那么它可能根本不会出现在对象代码中。如果对totherfunc()的调用说引用k没有被注释掉,那么k就必须在某个地方分配一个地址——它可能与i在同一段中。

The constant (if it is a constant, is it still a variable?) j will most probably appear on the stack of a conventional C implementation. (If you were asking in the comp.std.c news group, someone would mention that the standard doesn't say that automatic variables appear on the stack; fortunately, SO isn't comp.std.c!)

常量(如果它是常量,它仍然是一个变量吗?)j很可能出现在常规C实现的堆栈上。(如果你在报纸上问的话。c新闻集团,有人会说标准没有说自动变量出现在堆栈上;幸运的是,所以不是comp.std.c !)

Note that I forced the variables to appear because I passed them by reference - presumably to a function expecting a pointer to a constant integer. If the addresses were never taken, then j and k could be optimized out of the code altogether. To remove i, the compiler would have to know all the source code for the entire program - it is accessible in other translation units (source files), and so cannot as readily be removed. Doubly not if the program indulges in dynamic loading of shared libraries - one of those libraries might rely on that global variable.

注意,我强制让变量出现,因为我通过引用传递它们——可能是传递给一个函数,该函数期望指针指向一个常量整数。如果地址从未被占用,那么j和k可以从代码中完全优化。要删除i,编译器必须知道整个程序的所有源代码——它可以在其他翻译单元(源文件)中访问,因此不能轻易删除。如果程序沉溺于共享库的动态加载,那么这种情况就更糟糕了——其中一个库可能依赖于这个全局变量。

(Stylistically - the variables i and j should have longer, more meaningful names; this is only an example!)

(风格上——变量i和j应该有更长的、更有意义的名称;这只是一个例子!

#4


3  

Depends on your compiler, your system capabilities, your configuration while compiling.

依赖于编译器、系统功能、编译时的配置。

gcc puts read-only constants on the .text section, unless instructed otherwise.

gcc将只读常量放在.text部分,除非另有指示。

#5


1  

Usually they are stored in read-only data section (while global variables' section has write permissions). So, trying to modify constant by taking its address may result in access violation aka segfault.

通常它们存储在只读数据部分(而全局变量部分具有写权限)。因此,试图通过获取其地址来修改常量可能会导致访问被称为segfault。

But it depends on your hardware, OS and compiler really.

但这取决于你的硬件、操作系统和编译器。

#6


1  

This is mostly an educated guess, but I'd say that constants are usually stored in the actual CPU instructions of your compiled program, as immediate data. So in other words, most instructions include space for the address to get data from, but if it's a constant, the space can hold the value itself.

这主要是一种有根据的猜测,但我想说常量通常作为即时数据存储在编译程序的实际CPU指令中。换句话说,大多数指令包括地址空间,以获取数据,但如果它是常数,空间就能保持值本身。

#7


1  

offcourse not , because

offcourse不会,因为

1) bss segment stored non inilized variables it obviously another type is there.

1)bss段存储非inilized变量,显然有另一种类型。

       (I) large static and global and non constants and non initilaized variables it stored .BSS section.

       (II) second thing small static and global variables and non constants and non initilaized variables stored in .SBSS section this included in .BSS segment.

2) data segment is initlaized variables it has 3 types ,

2)数据段为内变量,有3种类型,

      (I) large static and global and initlaized and non constants variables its stord in .DATA section.
      (II) small static and global and non constant and initilaized variables its stord in .SDATA1 sectiion.
     (III) small static and global and  constant and initilaized OR non initilaized variables its stord in .SDATA2 sectiion.

i mention above small and large means depents upon complier for example small means < than 8 bytes and large means > than 8 bytes and equal values.

我前面提到过,大的和小的意味着依赖于编译器,例如,小的意味着小于8字节,大的意味着>大于8字节,并且值相等。

but my doubt is local constant are where it will stroe??????

但我的疑问是,局部常数会在哪里发生??????

#8


0  

Global and constant are two completely separated keywords. You can have one or the other, none or both.

全局和常量是两个完全分离的关键字。你可以有一个或另一个,没有或两者都有。

Where your variable, then, is stored in memory depends on the configuration. Read up a bit on the heap and the stack, that will give you some knowledge to ask more (and if I may, better and more specific) questions.

那么,存储在内存中的变量取决于配置。读一点堆和堆栈,这会给您一些知识来问更多的问题(如果可能的话,更好更具体)。

#9


0  

Some constants arfen't even stored.

有些常数甚至没有存储。

Consider the following code: int x = foo(); x *= 2;. Chances are that the compiler will turn the multiplication into x = x+x; as that reduces the need to load the number 2 from memory.

考虑以下代码:int x = foo();x * = 2,。编译器有可能把乘法运算变成x = x+x;这样就减少了从内存中加载数字2的需要。

#10


0  

It may not be stored at all.

它可能根本不会被存储。

Consider some code like this:

考虑以下代码:

#import<math.h>//import PI
double toRadian(int degree){
  return degree*PI*2/360.0;
}

This enables the programmer to gather the idea of what is going on, but the compiler can optimize away some of that, and most compilers do, by evaluating constant expressions at compile time, which means that the value PI may not be in the resulting program at all.

这使程序员能够收集正在发生的事情的想法,但是编译器可以通过在编译时计算常量表达式来优化其中的一部分,这意味着PI的值可能根本不在结果程序中。

#11


0  

Just as an an add on ,as you know that its during linking process the memory lay out of the final executable is decided .There is one more section called COMMON at which the common symbols from different input files are placed.This common section actually falls under the .bss section.

就像添加一样,您知道,在链接过程中,最终可执行文件的内存被决定了。这个公共部分实际上位于。bss部分之下。

#12


0  

It must be stored in Text segment as it is read-only variables. http://shirleyanengineer.blogspot.in/2017/05/memory-layout-of-process.html

它必须存储在文本段中,因为它是只读变量。http://shirleyanengineer.blogspot.in/2017/05/memory-layout-of-process.html