類型推斷的常量只能是標量值 - 即類似整數,雙精度等的東西。對於這些類型的常量,只要編譯器在表達式中滿足它們,就確實將常量的符號替換爲常量的值。
類型的常量,在另一方面,可以構成值 - 陣列和記錄。這些人需要在可執行文件中存儲實際的內容 - 即他們需要爲他們分配存儲空間,以便當操作系統加載可執行文件時,類型常量的值被物理地包含在內存中的某個位置。
爲了解釋爲什麼歷史上早期的Delphi及其前身Turbo Pascal中的鍵入常量是可寫的(因此基本上初始化全局變量),我們需要回到DOS的日子。
DOS運行在實模式,在86項。這意味着程序可以直接訪問物理內存而不需要任何虛擬物理映射。當程序直接訪問內存時,內存保護不起作用。換句話說,如果在任何給定地址上都有內存,則它在實模式下都是可讀寫的。
所以,在Turbo Pascal的程序DOS與類型化常數,其值在運行時內存在地址分配,這類型的常數將是可寫的。沒有硬件MMU妨礙程序寫入。同樣,由於Pascal沒有C++所具有的「常量」的概念,類型系統中沒有任何東西可以阻止你。很多人都利用了這一點,因爲當時Turbo Pascal和Delphi並沒有將全局變量初始化爲特徵。
移動到Windows,有存儲器地址與物理地址之間的層:存儲器管理單元。該芯片將獲取您試圖訪問的內存地址的頁面索引(移動掩碼),並在其page table中查找該頁面的屬性。這些屬性包括可讀,可寫,以及用於現代x86芯片的非可執行標誌。有了這種支持,就可以用屬性標記.EXE或.DLL的各個部分,以便Windows加載器將可執行映像加載到內存中時,它會爲映射到這些節中的磁盤頁的內存頁分配適當的頁面屬性。
當Delphi編譯器的32位Windows版本出現時,因此有意義的做const常量的東西真的是常量,因爲OS也具有此功能。
這樣做的伎倆。 Google顯示編譯器指令爲{$ J +}。 它也在項目選項中,可能應該看過那裏:P – Blorgbeard 2008-09-08 00:53:46
是的,我以前曾經被這個打擊過。 (編輯後添加細節後我的第一篇文章) – Ray 2008-09-08 00:58:22