コンパイラのほかにCを使用すると、指定された値のタイプを完全に把握しているため、指定された値のタイプを認識しているシステムはありません。
C自体は、実行時型情報システムを備えていないことに注意してください。
次の例を見てください。
int i_var;
double d_var;
int main () {
i_var = -23;
d_var = 0.1;
return 0;
}
コードには、整数として格納される値と倍精度値として格納される値の2種類の値が含まれています。
コードを分析するコンパイラは、両方の正確なタイプをよく知っています。ここで、生成コードがgccに渡されることによって生成される間に保持される型情報gccの短いフラグメントのダンプ-fdump-tree-all
:
@1 type_decl name: @2 type: @3 srcp: <built-in>:0
chan: @4
@2 identifier_node strg: int lngt: 3
@3 integer_type name: @1 size: @5 algn: 32
prec: 32 sign: signed min : @6
max : @7
...
@5 integer_cst type: @11 low : 32
@6 integer_cst type: @3 high: -1 low : -2147483648
@7 integer_cst type: @3 low : 2147483647
...
@3805 var_decl name: @3810 type: @3 srcp: main.c:3
chan: @3811 size: @5 algn: 32
used: 1
...
@3810 identifier_node strg: i_var lngt: 5
@linksを探すと、ノード@1-3および@に格納されているタイプ"int"のメモリサイズ、配置制約、および許可されている最小値と最大値について、実際に多くの情報が格納されていることがはっきりとわかります。 5-7。(前述の「 chan 」エントリは、生成されたツリー内のタイプ定義を追跡するために使用されるため、@ 4ノードを省略しました)
main.cの3行目で宣言されている変数については、ノード@3への型参照からわかるようにint型の値を保持していることがわかります。
自分でd_varのダブルエントリとd_varのエントリを自分で探し出すことができるはずです。信頼できない場合は、それらもそこにあります。
リストされている(gcc pass the -S
switchを使用して)生成されたアセンブラーコードを見ると、コンパイラーがコード生成でこの情報をどのように使用したかを見ることができます。
.file "main.c"
.comm i_var,4,4
.comm d_var,8,8
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
movl $-23, i_var
fldl .LC0
fstpl d_var
movl $0, %eax
popl %ebp
ret
.size main, .-main
.section .rodata
.align 8
.LC0:
.long -1717986918
.long 1069128089
.ident "GCC: (Debian 4.4.5-8) 4.4.5"
.section .note.GNU-stack,"",@progbits
割り当て命令を見ると、コンパイラがint値を割り当てるための正しい命令「mov」と「double」値を割り当てるための「fstp」を理解していることがわかります。
それにもかかわらず、マシンレベルで選択された指示以外に、それらの値のタイプの表示はありません。.LC0に格納されている値を見ると、値0.1のタイプ「double」は、アセンブラの既知の「タイプ」を満たすために、2つの連続する格納場所でそれぞれ長い間分解されていました。
実際のところ、この方法で値を分割することは、他の可能性の1つの選択肢にすぎず、「type」.byteの8つの連続した値を使用することも同様にうまくいきます。