ITエンジニアのブログ

IT企業でエンジニアやってる人間の日常について

プログラミング言語を作る。第14回:グローバル変数

プログラミング言語の開発について考えていたのですが、関数の部分適用など、いきなり実装するには難しい概念があるので、まずはC言語に似たプログラミング言語を作って概形を把握したいと思います。今回はグローバル変数について調査していました。普段はできるだけ静的スコープ内で変数を作って解決しようという意図でプログラミングをしているので、グローバル変数についてはあまり勝手が分かっていませんでした。ここで幾つか確認したいと思います。

#include <stdio.h>

char c = 'c';
short s = 12;
int i = 100;
float f = 3.4f;
long long ll = 123ll;
double d = 12.0;

int main(void){
    printf("%c\n", c);
    printf("%d\n", s);
    printf("%i\n", i);
    printf("%f\n", f);
    printf("%lld\n", ll);
    printf("%f\n", d);
    return 0;
}
        .file	"main.c"
.globl c
	.data
	.type	c, @object
	.size	c, 1
c:
	.byte	99
.globl s
	.align 2
	.type	s, @object
	.size	s, 2
s:
	.value	12
.globl i
	.align 4
	.type	i, @object
	.size	i, 4
i:
	.long	100
.globl f
	.align 4
	.type	f, @object
	.size	f, 4
f:
	.long	1079613850
.globl ll
	.align 8
	.type	ll, @object
	.size	ll, 8
ll:
	.quad	123
.globl d
	.align 8
	.type	d, @object
	.size	d, 8
d:
	.long	0
	.long	1076363264
	.section	.rodata
.LC0:
	.string	"%c\n"
.LC1:
	.string	"%d\n"
.LC2:
	.string	"%i\n"
.LC3:
	.string	"%f\n"
.LC4:
	.string	"%lld\n"
	.text
.globl main
	.type	main, @function
main:
.LFB0:
	.cfi_startproc
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register 6
	movzbl	c(%rip), %eax
	movsbl	%al, %edx
	movl	$.LC0, %eax
	movl	%edx, %esi
	movq	%rax, %rdi
	movl	$0, %eax
	call	printf
	movzwl	s(%rip), %eax
	movswl	%ax, %edx
	movl	$.LC1, %eax
	movl	%edx, %esi
	movq	%rax, %rdi
	movl	$0, %eax
	call	printf
	movl	i(%rip), %edx
	movl	$.LC2, %eax
	movl	%edx, %esi
	movq	%rax, %rdi
	movl	$0, %eax
	call	printf
	movss	f(%rip), %xmm0
	unpcklps	%xmm0, %xmm0
	cvtps2pd	%xmm0, %xmm0
	movl	$.LC3, %eax
	movq	%rax, %rdi
	movl	$1, %eax
	call	printf
	movq	ll(%rip), %rdx
	movl	$.LC4, %eax
	movq	%rdx, %rsi
	movq	%rax, %rdi
	movl	$0, %eax
	call	printf
	movsd	d(%rip), %xmm0
	movl	$.LC3, %eax
	movq	%rax, %rdi
	movl	$1, %eax
	call	printf
	movl	$0, %eax
	leave
	.cfi_def_cfa 7, 8
	ret
	.cfi_endproc
.LFE0:
	.size	main, .-main
	.ident	"GCC: (GNU) 4.4.7 20120313 (Red Hat 4.4.7-16)"
	.section	.note.GNU-stack,"",@progbits

align で幅を指定し、 byte, value, long, quad にて値を設定しているようです。グローバル変数の値の設定のときに、 i = 100 を i = 100 + 1 にしても GCC で動作しました。勝手に 101 に定数畳み込みで最適化されているようです。ところが、 atoi("43") のようにすると、初期化子は定数ではないとエラーが出力されました。