Как компилятор получает адрес const в C++?
Как обсуждается здесь какая область памяти является объектом const в C++?, компилятор, вероятно, не выделит любое хранилище для констант при компиляции кода они, вероятно, могут быть встроены непосредственно в машинный код. Тогда как компилятор получает адрес константы?
C++ код:
void f()
{
const int a = 99;
const int *p = &a;
printf("constant's value: %dn", *p);
}
3 ответов
будет ли константа выделена какое-либо хранилище или нет, полностью зависит от компилятора. Компиляторам разрешено выполнять оптимизацию в соответствии с , А Если правило, пока наблюдаемое поведение программы не меняется, компилятор может выделить память для a
или не может. Обратите внимание, что эти оптимизации не требуются, но разрешены стандартом.
очевидно, когда вы берете адрес этого const
компилятор придется вернуть вам адрес, по которому вы можете обратиться a
поэтому его придется разместить a
в памяти или по крайней мере притвориться, что это не так.
все переменные должны быть адресными. Компилятор мая оптимизировать постоянные переменные, но в таком случае, как ваш, где вы используете адрес переменной, он не может этого сделать.
компилятор может делать много трюков, которые разрешено делать до того момента, когда это повлияет на видимое поведение программы (см. как-если правило). Поэтому он может не выделять хранилище для const object const int a = 99;
, но в случае, когда вы берете адрес переменной-ему должно быть выделено некоторое хранилище или, по крайней мере, притворяться, и вы получите адрес памяти, который позволяет вам ссылаться наa
.
код:
#include <cstdlib>
using namespace std;
#include <cstdio>
const int a = 98;
void f()
{
const int a = 99;
const int *p = &a;
printf("constant's value: %d\n", *p);
}
int main(int argc, char** argv)
{
int b=100;
f();
return 0;
}
ССЗ -главный.cpp:
.file "main.cpp"
.section .rodata
.LC0:
.string "constant's value: %d\n"
.text
.globl _Z1fv
.type _Z1fv, @function
_Z1fv:
.LFB4:
.cfi_startproc
.cfi_personality 0x3,__gxx_personality_v0
pushq %rbp
.cfi_def_cfa_offset 16
movq %rsp, %rbp
.cfi_offset 6, -16
.cfi_def_cfa_register 6
subq , %rsp
movl , -4(%rbp)
leaq -4(%rbp), %rax
movq %rax, -16(%rbp)
movq -16(%rbp), %rax
movl (%rax), %eax
movl %eax, %esi
movl $.LC0, %edi
movl , %eax
call printf
leave
ret
.cfi_endproc
.LFE4:
.size _Z1fv, .-_Z1fv
.globl main
.type main, @function
main:
.LFB5:
.cfi_startproc
.cfi_personality 0x3,__gxx_personality_v0
pushq %rbp
.cfi_def_cfa_offset 16
movq %rsp, %rbp
.cfi_offset 6, -16
.cfi_def_cfa_register 6
subq , %rsp
movl %edi, -20(%rbp)
movq %rsi, -32(%rbp)
movl 0, -4(%rbp)
call _Z1fv
movl , %eax
leave
ret
.cfi_endproc
.LFE5:
.size main, .-main
.section .rodata
.align 4
.type _ZL1a, @object
.size _ZL1a, 4
_ZL1a:
.long 98
.ident "GCC: (Ubuntu/Linaro 4.4.7-2ubuntu1) 4.4.7"
.section .note.GNU-stack,"",@progbits
так мы видим, что переменная const int a = 99;
фактически встроен в машинный код, не находится в определенной области памяти (нет памяти в стеке, куче или выделенном ей сегменте данных). Пожалуйста, поправьте меня, если я ошибаюсь.