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