编译器如何在C ++中获取const的地址?

时间:2013-04-07 13:14:22

标签: c++ compilation const

正如此处Which memory area is a const object in in C++?所讨论的,编译器在编译代码时可能不会为常量分配任何存储,它们可能直接嵌入到机器代码中。然后编译器如何获得常量的地址?

C ++代码:

void f()
{
    const int a = 99;
    const int *p = &a;
    printf("constant's value: %d\n", *p);
}

3 个答案:

答案 0 :(得分:11)

是否将为任何存储分配常量完全取决于编译器。允许编译器按照 As-If 规则执行优化,只要程序的可观察行为没有改变,编译器就可以为a分配存储空间,也可能不会。请注意,标准不允许这些优化,但允许这些优化。

显然,当您获取此const的地址时,编译器必须返回一个地址,您可以通过该地址引用a,因此必须将a放入内存或至少假装它这样做。

答案 1 :(得分:2)

所有变量都必须是可寻址的。编译器可以优化常量变量,但在你使用变量地址的情况下,它不能这样做。

答案 2 :(得分:1)

编译器可能会执行许多技巧,这些技巧可能会影响程序的可见行为(请参阅as-if rule)。所以它可能不会为const对象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;
}

gcc -S main.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    $16, %rsp
    movl    $99, -4(%rbp)
    leaq    -4(%rbp), %rax
    movq    %rax, -16(%rbp)
    movq    -16(%rbp), %rax
    movl    (%rax), %eax
    movl    %eax, %esi
    movl    $.LC0, %edi
    movl    $0, %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    $32, %rsp
    movl    %edi, -20(%rbp)
    movq    %rsi, -32(%rbp)
    movl    $100, -4(%rbp)
    call    _Z1fv
    movl    $0, %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;实际上是在机器代码中构建的,不驻留在特定的内存区域(堆栈上没有内存,堆或分配给它的数据段) )。如果我错了,请纠正我。

相关问题