Как компилятор получает адрес 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; фактически встроен в машинный код, не находится в определенной области памяти (нет памяти в стеке, куче или выделенном ей сегменте данных). Пожалуйста, поправьте меня, если я ошибаюсь.