在 C 語言中,函數的回傳值不能是陣列類型。若嘗試宣告回傳 Matrix44f(即 float[16])的函數,編譯器會報錯。
typedef float Matrix44f[16];
Matrix44f translate(float x, float y, float z); // 編譯錯誤
Matrix44f scale(float x, float y, float z); // 編譯錯誤
// ... 其他函數同理
錯誤訊息通常為 "function returning an array" 或類似提示。
將回傳類型改為指向首元素的指標:
float *translate(float x, float y, float z);
float *scale(float x, float y, float z);
// ...
float *translate(float x, float y, float z) {
static Matrix44f M; // 使用 static 延長生命週期
for (int i=0; i<16; i++) M[i]=0;
M[3]=x; M[7]=y; M[11]=z; M[15]=1.0;
return M;
}
// 呼叫端
float *mat = translate(1.0f, 2.0f, 3.0f);
glUniformMatrix4fv(loc, 1, GL_TRUE, mat);
| 方案 | 優點 | 缺點 |
|---|---|---|
| 回傳指標 (static 區域變數) | 簡單,呼叫語法直觀 | 非執行緒安全,後續呼叫會覆蓋前次結果 |
| 呼叫端分配陣列,傳入指標 | 執行緒安全,生命週期由呼叫端控制 | 語法稍繁瑣 |
| 封裝於結構體中回傳 | 可直接回傳結構體(C99),語意清晰 | 複製開銷(通常經編譯器優化消除) |
void translate(Matrix44f out, float x, float y, float z) {
for (int i=0; i<16; i++) out[i]=0;
out[3]=x; out[7]=y; out[11]=z; out[15]=1.0;
}
// 使用
Matrix44f mat;
translate(mat, 1,2,3);
此模式為 C 語言標準庫慣用風格(如 strcpy、memcpy),執行緒安全、無額外分配、意圖明確。