直到今天,我一直認爲體面編譯器會自動將結構傳遞值轉換爲傳遞引用,如果結構足夠大,後者會更快。據我所知,這似乎是一個不費吹灰之力的優化。然而,爲了滿足我對這是否真的發生的好奇心,我在C++和D中創建了一個簡單的測試用例,並查看了GCC和Digital Mars D的輸出。兩者都堅持按值傳遞32字節的結構,有問題的函數是加起來的成員和返回的值,沒有修改傳入的結構。C++版本如下。爲什麼不通過引用傳遞結構通用優化?
#include "iostream.h"
struct S {
int i, j, k, l, m, n, o, p;
};
int foo(S s) {
return s.i + s.j + s.k + s.l + s.m + s.n + s.o + s.p;
}
int main() {
S s;
int bar = foo(s);
cout << bar;
}
我的問題是,爲什麼赫克不會像這樣由編譯器優化,以傳遞通過引用,而不是實際推動所有這些int
小號到堆棧?注:使用的編譯器開關:GCC -O2(-O3內聯foo()。),DMD -O -inline -release。
編輯:顯然,在通常情況下,傳值與傳遞引用的語義不會相同,例如,如果涉及到複製構造函數或原始結構在被調用方中被修改。然而,在很多現實場景中,語義在可觀察行爲方面將是相同的。這些是我所問的情況。
當進行鏈接時間優化,也就是鏈接時間代碼生成或整個程序編譯時,編譯器不需要僅基於聲明來編譯該調用。它充分了解發生了什麼。爲了編譯對大小和速度敏感的嵌入式應用程序,鏈接時間代碼生成是唯一的方法。 – 2015-02-03 16:16:22