C# 16 重新設計 unsafe 語意:從範圍標記到合約機制
Microsoft .NET Developer Blog · 2026-05-24
Microsoft 在 .NET 部落格發布 C# 16 的 unsafe 語意重設計提案,預計隨 .NET 11 preview 推出、.NET 12 生產釋出。核心思路是把 unsafe 從「語法範圍標記」改為「呼叫者合約」——一種編譯器無法驗證、必須由開發者閱讀並遵守的義務聲明。
核心改動
強制 inner block 是主要的視覺性變更:即使方法本身已標記 unsafe,所有不安全操作仍必須包裹在內部 unsafe { } 區塊中。這讓 code review 時的危險點一目了然,無需逐行追蹤 unsafe 方法範圍。
新增 /// <safety> XML 註解區塊,正式記錄呼叫者必須滿足的前提條件,取代過去靠注釋或慣例傳遞的隱性義務。指標型別在方法簽章中不再自動傳播 unsafety,只有實際的指標解參考才是 unsafe 操作,需要 extern 宣告加入 safe 關鍵字。
欄位與傳播模型
欄位可標記 unsafe 以保護型別系統無法表達的不變量,常見情境包含原生指標欄位與緊密耦合的欄位對。方法可選擇兩種模式:將 unsafety 向上傳播(在方法簽章標記 unsafe),或在邊界消化它(提供 runtime guard 和靜態驗證,讓呼叫者感知不到 unsafe)。
相容性與遷移
專案層級有兩個獨立開關:選入 C# 16 unsafe 模型的新屬性,以及現有的 AllowUnsafeBlocks。選入新模型的呼叫者消費舊版函式庫時會進入相容模式,視指標型別參數為 unsafe;舊版程式碼消費選入新模型的套件時則不受影響,維持向下相容。
與 Rust 的比較:傳播語意相近,但 C# 選擇顯式 unsafe 標記而非 Rust 的型別系統內建追蹤,優先考量 greppability 與 audit 流程的明確性。
原始來源:Microsoft .NET Blog
z386:以原始微碼為核心重建的開源 80386 FPGA 處理器
nand2mario.github.io · 2026-05-24
z386 是一個在 FPGA 上實作的 80386 相容處理器,其獨特之處在於直接執行從真實 Intel 80386 晶片提取的原始微碼,而非重新撰寫指令行為。這個專案由 80386 微碼反組譯工作所觸發,目前已能在 Cyclone V 和 Gowin GW5A FPGA 上成功啟動 DOS 6/7,並執行使用 DOS/4GW extender 的保護模式程式(包含 Doom)。
架構設計
z386 對應 Intel 的硬體設計拆分為八個功能單元:
- Prefetch unit:維護 16 位元組指令佇列
- Decoder:透過 Control PLA 和 Entry PLA 將指令位元組映射到微碼進入點
- Microcode sequencer:執行 2,560 條 37 位元微碼字
- ALU / shifter:算術、邏輯與位移運算
- Segmentation unit:邏輯到線性位址轉換
- Protection unit:透過 Protection PLA 驗證 selector 與 descriptor
- Paging unit:TLB、page walk 與實體位址轉換
- Memory / cache:16KB 四路組合關聯 L1 cache,使用 VIPT(virtually indexed, physically tagged)查找
微碼執行細節
解碼器採雙 PLA 設計:Control PLA 決定結構性元素(前綴、ModR/M 位元組),Entry PLA 識別微碼進入點,使解碼可隨指令位元組逐步進行。每條微碼字控制資料路徑路由、ALU 操作與 sequencer 行為,關鍵設計包含分支後的 delay slot、Protection PLA 重導向的三週期延遲,以及中斷處理的 RNI(run-next-instruction)變體。
效能與比較
與另一個 FPGA x86 核心 ao486 相比:z386 程式碼量較小(8K vs 17.6K 行),資源使用量較低(18K vs 21K ALUTs),執行 3DBench 達 34 FPS(ao486 為 43 FPS)。整體約等於低端 486 效能。
開發過程採用系統化測試:先用 SingleStepTests 套件進行單指令模糊測試,再以 86Box 作為參考平台進行保護模式測試。DOS extender(如 DOS/4GW)相容性問題則透過 Ghidra 反組譯後逐一修正。