Onde as variables ​​constantes são armazenadas em C?

Eu me pergunto onde as variables ​​constantes são armazenadas. Está na mesma área de memory que as variables ​​globais? Ou está na pilha?

Como eles são armazenados é um detalhe de implementação (depende do compilador).

Por exemplo, no compilador GCC, na maioria das máquinas, variables ​​de leitura, constantes e tabelas de salto são colocadas na seção de texto.

Dependendo da segmentação de dados que um determinado processador segue, temos cinco segmentos:

  1. Segmento de Código – Armazena apenas código, ROM
  2. Segmento BSS (ou Block Started by Symbols) – Armazena variables ​​globais e estáticas inicializadas
  3. Segmento de pilha – armazena todos os varialbles locais e outras informações relativas ao endereço de retorno de function, etc.
  4. Segmento de heap – todas as alocações dinâmicas acontecem aqui
  5. Segmento de dados – armazena variables ​​globais e estáticas não inicializadas

Observe que a diferença entre o BSS e o segmento de dados é que o antigo armazenamento inicializou varialbes globais e estáticos e o posterior armazena os não inicializados.

Agora, por que eu estou falando sobre a segmentação de dados quando devo estar dizendo onde estão as variables ​​constantes armazenadas … há uma razão para isso …

Cada segmento tem uma região protegida contra gravação, onde todas as constantes são armazenadas.

Por exemplo,

se eu tiver um const int que é variável local, então ele é armazenado na região protegida contra gravação do segmento de pilha. e se eu tenho um global que é inicializado const var, então ele é armazenado no BSS e se eu tiver um const var não inicializado, ele é armazenado no segmento de dados …

Para resumir, “const” é apenas um dado QUALIFIER, o que significa que primeiro o compilador tem que decidir qual segmento a variável deve ser armazenada e então se a variável é uma const, então ela se qualifica para ser armazenada na região protegida contra gravação. esse segmento particular.

Espero que isso esclareça a maioria dos mal-entendidos … 🙂

Quaisquer comentários adicionais são bem-vindos … 🙂

Considere o código:

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); } 

Geralmente, i posso ser armazenado no segmento de texto (é uma variável somente leitura com um valor fixo). Se não estiver no segmento de texto, ele será armazenado ao lado das variables ​​globais. Dado que ele é inicializado para zero, ele pode estar na seção ‘bss’ (onde as variables ​​zeradas são normalmente alocadas) ou na seção ‘data’ (onde as variables ​​inicializadas são geralmente alocadas).

Se o compilador estiver convencido de que o k não está sendo usado (o que poderia ser uma vez que é local para um único arquivo), ele pode não aparecer no código de object. Se a chamada para totherfunc() que referencia k não foi comentada, então k teria que ser alocado um endereço em algum lugar – provavelmente estaria no mesmo segmento que i .

A constante (se é uma constante, ainda é uma variável?) j provavelmente aparecerá na pilha de uma implementação C convencional. (Se você estivesse perguntando no grupo de notícias comp.std.c, alguém mencionaria que o padrão não diz que variables ​​automáticas aparecem na pilha; felizmente, SO não é comp.std.c!)

Note que forcei as variables ​​a aparecer porque as passei por referência – presumivelmente para uma function esperando um ponteiro para um inteiro constante. Se os endereços nunca fossem tirados, então j e k poderiam ser otimizados para fora do código. Para remover o i , o compilador teria que conhecer todo o código-fonte de todo o programa – ele pode ser acessado em outras unidades de tradução (arquivos de origem) e, portanto, não pode ser removido com facilidade. Doubly não se o programa dedicar-se ao carregamento dynamic de bibliotecas compartilhadas – uma dessas bibliotecas pode depender dessa variável global.

(Estilisticamente – as variables i j devem ter nomes mais longos e significativos; isso é apenas um exemplo!)

Depende do seu compilador, seus resources de sistema, sua configuração durante a compilation.

gcc coloca constantes somente leitura na seção .text , a menos que seja instruído de outra forma.

Geralmente eles são armazenados em uma seção de dados somente leitura (enquanto a seção de variables ​​globais tem permissions de gravação). Portanto, tentar modificar a constante, obtendo seu endereço, pode resultar em violação de access, também conhecido como segfault.

Mas isso depende do seu hardware, sistema operacional e compilador.

Este é principalmente um palpite, mas eu diria que as constantes são normalmente armazenadas nas instruções reais da CPU do seu programa compilado, como dados imediatos. Em outras palavras, a maioria das instruções inclui espaço para o endereço obter dados, mas se for uma constante, o espaço pode conter o valor em si.

Claro que não, porque

1) segmento bss armazenado variables ​​não inilizadas, obviamente, outro tipo está lá.

  (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) segmento de dados é variables ​​iniciadas possui 3 tipos,

  (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. 

Eu mencionei acima de médias pequenas e grandes depende do complier, por exemplo, médias pequenas de 8 bytes e valores iguais.

mas a minha dúvida é a constante local é onde vai stroe ????

Global e constante são duas palavras-chave completamente separadas. Você pode ter um ou outro, nenhum ou ambos.

Onde sua variável, então, é armazenada na memory depende da configuração. Leia um pouco sobre o heap e a pilha , que lhe dará algum conhecimento para fazer mais perguntas (e se eu puder, melhor e mais específico).

Algumas constantes nem sequer são armazenadas.

Considere o seguinte código: int x = foo(); x *= 2; int x = foo(); x *= 2; . As chances são de que o compilador irá transformar a multiplicação em x = x+x; como isso reduz a necessidade de carregar o número 2 da memory.

Pode não ser armazenado de todo.

Considere algum código como este:

 #import//import PI double toRadian(int degree){ return degree*PI*2/360.0; } 

Isso permite ao programador reunir a ideia do que está acontecendo, mas o compilador pode otimizar parte disso, e a maioria dos compiladores, avaliando expressões constantes em tempo de compilation, o que significa que o valor PI pode não estar no programa resultante em absoluto.

Assim como um complemento, como você sabe que durante o processo de vinculação, a memory exposta do executável final é decidida. Há mais uma seção chamada COMMON na qual os símbolos comuns de diferentes arquivos de input são colocados. sob a seção .bss.

Ele deve ser armazenado no segmento de texto, pois é uma variável somente leitura. http://shirleyanengineer.blogspot.in/2017/05/memory-layout-of-process.html