2014-11-14 95 views
1

考慮follwing C++代碼的情況下不增加:碼量的內聯函數

#include <iostream> 

using namespace std; 

class A 
{ 
    int a; 
    public: 
     A(); 
     void f(); 
}; 

A::A() 
{ 
    cout<<"Constructor"<<endl; 
} 

inline void A::f() 
{ 
    cout << "hello\n"; 
} 

int main() 
{ 
    A a; 
    a.f(); 
    a.f(); 
    a.f(); 
    return 0; 
} 

這裏的函數f由我做內聯。現在我運行size命令來查找文本部分的大小。我得到了以下輸出:

text  data  bss  dec  hex filename 
2148  312  144 2604  a2c ./1 

現在我通過從其定義中刪除inline關鍵字,使函數f非內聯。在我又跑了大小命令:

text  data  bss  dec  hex filename 
2148  312  144 2604  a2c ./1 

所以,文本部分的大小是在兩種情況下相同的,雖然我預計大小爲更大的情況下,f爲直列其調用只是通過更換內聯代碼。

那麼,這可能是什麼原因?有沒有任何例子的尺寸會改變?

+0

'inline'是一個建議,不能保證編譯器實際上會內聯你的函數。 – 2014-11-14 17:41:45

+0

@CaptainObvlious:但是如果代碼大小增加,增加將是可見的。它與對齊有什麼關係? – tapananand 2014-11-14 17:42:44

+0

您的編譯器可能會忽略'inline',至少就決定是否爲內聯函數生成代碼(雖然inline也影響單定義規則的方式不能忽略)。順便說一句,幾乎愚弄:http://stackoverflow.com/q/1759300/179910 – 2014-11-14 17:43:14

回答

1

在這種情況下,這可能是鏈接時間優化的情況。這通過使用g++ -S 1.cpp 編譯代碼的事實得到證實。內聯的彙編代碼的大小比非內聯的彙編代碼的大小要大。所以,實際的行爲可以在彙編中看到,但在鏈接時間之後不能在最終執行。

0

內聯只是一個對編譯器的請求。它可能會也可能不會像內聯那樣執行該功能。

+0

這幾天,它甚至不是一個請求。現代編譯器將「內聯」說明符的作用限制爲只放寬ODR。至於實際內聯,他們更喜歡他們自己的判斷。 – ach 2014-11-14 17:50:51

3

inline不影響函數調用是否內聯(儘管它可能或可能不影響編譯器的決定)。只要不改變程序的行爲,編譯器就可以根據「as-if」規則自由地內聯任何函數調用,任何優化都是允許的。

inline的目的是允許您定義頭中的函數,給出多個定義(每個翻譯單元中包含頭的一個定義),否則這些定義將被One Definition Rule禁止。對於某些編譯器,這是允許內聯函數調用所必需的 - 除非它具有鏈接時優化器,編譯器只能在定義可用時內聯調用函數。

如果你使用GCC,那麼就可以用它來防止內聯,如果你想看到效果的屬性:

void f() __attribute__ ((noinline)); 
+0

甚至指定函數f的屬性不會顯示效果。請幫忙!! – tapananand 2014-11-14 17:50:48

+0

@TapanAnand:您是否在優化建設?它可能不會內聯函數。 – 2014-11-14 17:54:06

2

既然你在一個文件中的所有代碼,最有可能的編譯器在兩種情況下內聯A::f

Here is a demo在您的代碼中顯示此內容。

比檢查文本段大小更好,您可以指定-S編譯器選項並比較兩個版本的彙編輸出。