読者です 読者をやめる 読者になる 読者になる

Let's write β

趣味で書いたこととか、RustとLispが好き

変数のスコープのコンパイル

C/C++
#include <stdio.h>

main()
{
        volatile int x = 0, y = 1, z = 2;
        printf("0. x = %d, y = %d, z = %d\n", x, y, z);
        {
                volatile y = 2, z = 3;
                printf("1. x = %d, y = %d, z = %d\n", x, y, z);
                {
                        volatile z = 4;

                        printf("2. x = %d, y = %d, z = %d\n", x, y, z);
                }
                printf("1. x = %d, y = %d, z = %d\n", x, y, z);
        }
        printf("0. x = %d, y = %d, z = %d\n", x, y, z);
        return 0;
}

コンパイルすると、長ったらしいのでmainだけ

main:
.LFB0:
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        pushq   %rbx
        subq    $40, %rsp
        movl    $0, -20(%rbp)
        movl    $1, -24(%rbp)
        movl    $2, -28(%rbp)
        movl    -28(%rbp), %ecx
        movl    -24(%rbp), %edx
        movl    -20(%rbp), %ebx
        .cfi_offset 3, -24
        movl    $.LC0, %eax
        movl    %ebx, %esi
        movq    %rax, %rdi
        movl    $0, %eax
        call    printf
        movl    $2, -32(%rbp)
        movl    $3, -36(%rbp)
        movl    -36(%rbp), %ecx
        movl    -32(%rbp), %edx
        movl    -20(%rbp), %ebx
        movl    $.LC1, %eax
        movl    %ebx, %esi
        movq    %rax, %rdi
        movl    $0, %eax
        call    printf
        movl    $4, -40(%rbp)
        movl    -40(%rbp), %ecx
        movl    -32(%rbp), %edx
        movl    -20(%rbp), %ebx
        movl    $.LC2, %eax
        movl    %ebx, %esi
        movq    %rax, %rdi
        movl    $0, %eax
        call    printf
        movl    -36(%rbp), %ecx
        movl    -32(%rbp), %edx
        movl    -20(%rbp), %ebx
        movl    $.LC1, %eax
        movl    %ebx, %esi
        movq    %rax, %rdi
        movl    $0, %eax
        call    printf
        movl    -28(%rbp), %ecx
        movl    -24(%rbp), %edx
        movl    -20(%rbp), %ebx
        movl    $.LC0, %eax
        movl    %ebx, %esi
        movq    %rax, %rdi
        movl    $0, %eax
        call    printf
        movl    $0, %eax
        addq    $40, %rsp
        popq    %rbx
        leave
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc

当然スコープが反映されてます。どうやってコンパイルしてるんだろう、
スコープで宣言される度に何か変数のバインドをマークしておいて
スタックにつんで言って、参照先はスタックの上から参照していくことで
ちゃんと最後に定義されたものが参照されるとかそういうのかな?

僕が働いているAzit.incでは一緒に働けるエンジニアを募集しています!
採用情報 — 株式会社アジット|Azit Inc.