2015-02-06 43 views
4

寫在C便攜式功能(沒有組件),該返回嘗試它的堆棧幀便攜式函數,返回它的堆棧幀的大小

int stackframe_size() 
{ 

} 

的解決它的大小below - 該函數在使用VS 2010進行編譯時返回228個字節。有沒有一種方法可以驗證其正確性?

int stackframe_size(int run) 
    { 
     int i ; 

     if(!run) 
     { 
      return ((int)(&i) - stackframe_size(++run)); 

     } 
     return (int)(&i); 

    } 

援引爲:

int main() 
    { 
     printf("\nSize of stackframe_size() is: %d bytes",stackframe_size(0)) ; 
     return 0; 
    } 
+0

:)我問這個,因爲我想檢查是否有一個聰明/清潔的方式來做到這一點,而無需添加讀取參數地址的本地變量(比如使用遞歸技術)。 – Electrix 2015-02-06 03:49:15

+0

聽起來像是一個很好的技術給我。也許你應該分享這些代碼,並解釋它的工作原理和結果。 – user3386109 2015-02-06 03:55:20

+2

你不能擁有這樣的*便攜*功能。一個假想的整體程序優化編譯器可能*有時*沒有任何堆棧生成代碼;人們可以想象一些沒有堆棧的C編譯器(但是在一些垃圾收集堆中分配所有的調用幀,就像SML/NJ一樣)。所以原則上,甚至不需要堆棧。但是我知道沒有這種奇怪的C實現沒有堆棧! – 2015-02-06 16:54:36

回答

5

沒有這樣的便攜式功能是可能的。

您的嘗試可能與您所能得到的儘可能接近,但指針減法具有未定義的行爲。更一般地,p1 - p0,其中p0p1是指向不同對象的指針,具有未定義的行爲。

除您的代碼減去int作爲地址轉換結果的值之外。直接減去指針更有可能 - 而指針應該是char*unsigned char*。有很多實現,其中int太小而無法容納轉換的指針,有些指針的表示比您想象的更復雜,並且將它們轉換爲足夠大的整數類型不一定會給您帶來有意義的結果。

現實世界中的C實現不使用「堆棧」來表示「堆棧幀」被推送和彈出的連續內存區域。 (從先入後出的數據結構來看,必須有一個「堆棧」,但實現「堆棧」的方式完全沒有規定)。例如,一些IBM大型機實現爲函數分配內存通過類似堆的方式進行調用,以便兩個此類調用的局部變量的地址之間沒有定義的關係。

你可以在純C中編寫一個函數(沒有彙編語言),該函數爲特定的實現提供了一個棧幀的大小。但是由於C語言本身沒有「棧幀」的概念(標準甚至沒有使用「棧」這個詞),所以它不能被輕易地完成。

+0

「沒有這樣的便攜式功能是可能的」的榮譽 - C實現甚至不需要有堆棧。 – paxdiablo 2015-04-16 06:59:26

1

我想檢查是否有這樣做不會增加局部變量

你可以使用&run而不是一個聰明的/乾淨的方式&i - 這將爲您節省一個本地變量。

有沒有辦法驗證它的正確性?

使用調試器!檢查堆棧指針寄存器在你關注的位置,觀察發生溢出等。