2010-01-08 90 views
2

編譯器是否會爲這兩種語句生成相同的代碼?c/C++通過參考堆棧幀佈局的指針/參數傳遞參數

foo1(int* val){(*val)++;} 

foo2(int &val){val++;} 

它只是寫一個指針到foo的棧幀的參數部分嗎?或者,在第二種情況下,調用者和foos的堆棧框架會以某種方式重疊,這樣調用者的局部變量會將棧中的內存作爲foo的參數?

+0

應該完全一樣。每當懷疑這些情況時,最好檢查一下拆卸情況。 – Andy 2010-01-08 13:46:55

回答

0

堆棧不能重疊。

認爲說法可能是全球性的,一個堆對象,或者即使存儲在堆棧中它可能是不是最後一個元素。根據調用約定,其他元素可能放置在一個堆棧幀和傳遞給函數的參數(即返回地址)之間...

並注意,即使堆棧中沒有添加任何內容,決策也不能在編譯函數時進行,而是在編譯器正在處理調用函數時進行。一旦函數編譯完成,它將不會根據調用的位置而改變。

+0

我認爲提及鏈接器內聯可能不適合這個問題。 – 2013-06-27 17:30:00

4

這兩個呼叫應產生完全相同的代碼,除非你有某種奇怪的編譯器。

2

這取決於。

如果編譯到一個庫兩者生成的代碼將是等價的,如果在大多數平臺上不相同的。

任何一個優秀的編譯器將內聯這樣的小功能,所以它很可能是,而不是得到的東西的地址在棧上遞增指向的值,它會而不是直接增加值。任何內聯函數的堆棧幀都嵌入在調用者的堆棧幀中,所以在這種情況下會重疊。

+0

所以也需要一個指針的版本會被內聯,而不是使用一個指針,直接在實際變量上工作? – Mat 2010-01-08 14:48:30

+0

@Mat:參考版本也可以內聯。 – 2010-01-08 17:27:56

+0

@Mat:兩者都可以內聯直接在實際變量上工作。 – 2013-06-27 17:30:47

0

關於堆棧幀的重疊我發現下面的信息here

爲了某些目的,子例程的堆棧幀和它的調用者的可以被認爲是重疊,重疊組成的區域的其中參數從調用者傳遞給被調用者。在某些環境中,調用者將每個參數壓入堆棧,從而擴展其堆棧幀,然後調用被調用者。在其他環境中,調用者在其堆棧框架的頂部有一個預分配區域,用於保存向其調用的其他子例程提供的參數。此區域有時稱爲傳出參數區域或標註區域。在這種方法下,編譯器計算區域的大小是任何被調用子程序所需的最大值。

所以你的情況,如果僅在調用函數本地作用域的變量傳遞給foo2的重疊事情是可能的!