首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

編譯器前端核心:UCC 中間代碼生成中陣列與結構體成員的偏移量計算機制

     編輯:關於C

背景:基址 + 偏移 統一尋址模型

陣列元素 arr[i][j]、結構體成員 st.m 皆可表示為 基址 + 常量偏移 + 變量偏移。UCC 在中間代碼層統一處理。

中間代碼層符號表示

  • 臨時變數 t 承載地址運算結果。
  • Offset(addr, voff, coff) 產生地址運算中間碼:
t1 = &arr;           // 取基址
t2 = i * 4;          // 變量偏移
t3 = t1 + t2 + 8;    // 基址 + 變量偏移 + 常量偏移
*t3 = 30;            // 間接賦值

核心函數 Offset

  • 參數 base:基址符號(陣列名、結構體變數、指標)。
  • voff:變量偏移符號(如 i*4),無則 NULL。
  • coff:常量偏移位元組數(如結構體成員偏移、陣列固定索引)。
  • 流程:依序產生加法中間碼,最後 Deref 產生間接尋址節點。

CreateOffset:建立偏移符號節點

  • 為 基址+常量偏移 創建新符號(型別 SK_Offset),記錄基址符號指標與偏移值。
  • 名稱編碼為 arr[8] 形式,便於除錯。
  • 若基址本身為偏移符號(如 st.arr[2]),遞迴合併偏移(st 偏移 4 + arr[2] 偏移 8 = 12)。
  • 避免將指標運算 (*ptr)[2] 錯誤降級為 ptr[8],必須保留間接層級。

Deref 與 AddressOf

  • Deref(t):產生 t2 = *t1,返回新臨時變數;若 t1 來自 &arr,簡化為直接訪問 arr。
  • AddressOf(t):&*t 簡化為 t;對左值生成取址指令並標記 addressed=1,使相關公共子運算式失效(規避別名分析)。

陣列名語意特例

語境表達式類型說明
sizeof(arr)int[4]完整陣列類型
arr + 1int*退化為首元素指標
&arr + 1int(*)[4]陣列指標類型

C 編譯器根據上下文自動退化,源於早期效率考量(函數傳遞陣列避免複製)。現代建議:明確使用指標參數 int *p 或 int (*p)[N] 表達意圖。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved