ページ 1 / 1
ポインタのキャストにおけるメモリのアロケーション
Posted: 2016年1月26日(火) 07:14
by lisp implementer
お世話になります。
ある型へのポインタを別の型へのポインタにキャストする時、型変換の結果を新たな変数に代入しない場合にも、新たなメモリ領域がアロケートされているのでしょうか? それとも元のポインタのメモリ領域を別の型として解釈し直しているのでしょうか? やや細かい質問ですが、よろしくお願いします。
Re: ポインタのキャストにおけるメモリのアロケーション
Posted: 2016年1月26日(火) 08:06
by みけCAT
コンパイラやインタプリタの実装によるかもしれません。
あるコンパイラの仕様を推測するには、コンパイラの出力するアセンブリコードを読むといいでしょう。
Re: ポインタのキャストにおけるメモリのアロケーション
Posted: 2016年1月26日(火) 22:55
by lisp implementer
ありがとうございます。簡単なテストコードを書いてアセンブリコード化してみました。
コード:
#include <stdint.h>
#include <stdio.h>
int main() {
void *p;
printf("%llu\n", (uint64_t)(p));
return 0;
}
このコードと、
コード:
#include <stdint.h>
#include <stdio.h>
int main() {
void *p;
printf("%llu\n", (uint64_t)((int *)(p)));
return 0;
}
このコードを比較したところ、一つ目のコードのアセンブリコードが以下のようになり、
コード:
pushq %rbp
Ltmp0:
.cfi_def_cfa_offset 16
Ltmp1:
.cfi_offset %rbp, -16
movq %rsp, %rbp
Ltmp2:
.cfi_def_cfa_register %rbp
subq $32, %rsp
leaq L_.str(%rip), %rdi
movl $0, -4(%rbp)
movq -16(%rbp), %rsi
movb $0, %al
callq _printf
xorl %ecx, %ecx
movl %eax, -20(%rbp) ## 4-byte Spill
movl %ecx, %eax
addq $32, %rsp
popq %rbp
retq
ポインタをキャストしたほうのコードが以下のようになりました。
コード:
pushq %rbp
Ltmp0:
.cfi_def_cfa_offset 16
Ltmp1:
.cfi_offset %rbp, -16
movq %rsp, %rbp
Ltmp2:
.cfi_def_cfa_register %rbp
subq $32, %rsp
leaq L_.str(%rip), %rdi
movl $0, -4(%rbp)
movq -16(%rbp), %rax
movq %rax, %rsi
movb $0, %al
callq _printf
xorl %ecx, %ecx
movl %eax, -20(%rbp) ## 4-byte Spill
movl %ecx, %eax
addq $32, %rsp
popq %rbp
retq
変わった箇所は一つで、
movq -16(%rbp), %rsi
これが
movq -16(%rbp), %rax
movq %rax, %rsi
こうなったようです。アセンブリはほとんど分からないのですが、これは新たにメモリ領域が確保されているということで良いのですよね?
単純にアセンブリコードを比較するとコンパイラ側で簡単に最適化できそうなものですが、Cのコードに忠実にコンパイルするように出来ているのでしょうか。
Re: ポインタのキャストにおけるメモリのアロケーション
Posted: 2016年1月26日(火) 23:11
by みけCAT
lisp implementer さんが書きました:これは新たにメモリ領域が確保されているということで良いのですよね?
プログラムのサイズが増えるという意味ではメモリ領域が確保されているかもしれない(ページ単位などに切り上げると変わらないかもしれない)ですが、
単にポインタの値を一旦レジスタに格納しているだけなので、データ用のメモリ領域が新たに確保されているとはいえないでしょう。
lisp implementer さんが書きました:単純にアセンブリコードを比較するとコンパイラ側で簡単に最適化できそうなものですが、Cのコードに忠実にコンパイルするように出来ているのでしょうか。
コンパイラとコンパイルオプションによるでしょう。
Re: ポインタのキャストにおけるメモリのアロケーション
Posted: 2016年1月27日(水) 00:28
by lisp implementer
よく分かりました。ありがとうございます。アセンブリのmovを誤解していたようです。
キャストのコストは一応あるものの、メモリ内ではなくCPU内でのステップが1つ増えるだけならば、それほどのコストではないというところでしょうか。ありがとうございました。助かりました。