使用ç除了編譯器,是非常清楚知道的給定值的類型沒有系統是知道了給定值的類型。
請注意,C本身不帶任何運行時類型信息系統。
看看下面的例子:
int i_var;
double d_var;
int main() {
i_var = -23;
d_var = 0.1;
return 0;
}
在代碼有兩種不同類型的涉及一個值將被存儲爲一個整數和一個將被存儲爲一個雙精度值。
分析代碼的編譯器非常瞭解它們的確切類型。這裏的類型信息的gcc很短的片段,而通過將-fdump-tree-all
到GCC生成的代碼生成舉行的轉儲:
@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和@ 5-7中的類型「int」的最小值和最大值。 (我離開了@ 4節點作爲提到的「Chan」的條目只是用來茶我Ñ起來在所生成的樹的任何類型的定義)在main.c中第3行聲明
Reagarding可變它是已知的,它保存了一個類型爲int的值,如對節點@ 3的類型引用所看到的。
如果你不相信我,他們也會在那裏,你一定能夠在自己的實驗中追捕d_var的雙重條目和那些條目。
以看看所生成的彙編程序代碼(使用gcc通過-S
開關)中列出,我們可以看看編譯器使用在代碼生成這種信息的方式:
.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
以看看您將看到編譯器找出正確的指令「mov」來分配我們的int值,「fstp」分配我們的「double」值。
儘管如此,除了在機器級選擇的指令,沒有指示這些值的類型。查看.LC0中存儲的值,值爲0.1的類型「double」甚至在兩個連續的存儲位置中被分解,每個存儲位置很長以滿足已知的「類型」彙編器。
事實上,通過這種方式打破價值只是其他可能性的一種選擇,使用8個「type」字節的連續值可以取得同樣的效果。
請參閱:http://en.wikipedia.org/wiki/Symbol_table – 2013-03-01 17:24:46
C中的每個變量都必須有一個類型作爲變量聲明的一部分(可能的定義,從來不知道是哪個)。編譯器讀取類型並記住它。關於變量的類型沒有神祕感。 – DwB 2013-03-01 17:25:37
編譯器將使用正確的指令(因爲無符號和有符號可以用標準中規定的規則派生)。對於符號和無符號計算有不同的說明,至少對於我所見過的體系結構。對於C,在運行時不會存儲有關類型的附加信息。 – nhahtdh 2013-03-01 17:26:19