C 內聯函式和constexpr函式可以在程式中定義不止一次,這個一般用在什麼時候?

時間 2021-05-11 00:43:29

1樓:楊個毛

用來讓你製造一堆weak symbol,然後一不小心試圖把兩個不同libstdc++版本的.o檔案鏈結在一起的時候死得不明不白的。

2樓:Pluto Hades

你們為什麼搞這麼複雜?inline關鍵字是在宣告的時候用的,不是在定義的時候寫。題主你把inline和函式體挪到頭檔案再試一次。

另外,C++類成員函式直接在標頭檔案寫實現預設就是內聯的,不加inline也沒關係

3樓:藍色

對於內聯函式而言,其比較大的特點就是會在函式呼叫的地方被直接展開,而不是乙個函式呼叫,從而減少函式的呼叫開銷。而若是函式呼叫的話,我們可以在使用函式前的時候,如int foo()的方式,然後讓後面的鏈結器去其它的目標檔案進行函式符號的查詢。

我來仔細的一步一步的分析這裡面產生的緣由,我使用gcc作為演示,因為Linux有一系列的工具可以方便檢視,但是這和Visual C++的原理是一致的。

回到你的例子,我們使用g++ -c http://

main.cc

-o main.o,然後使用nm main.o | c++filt 來檢視生成的符號,如下圖所示:

我們可以很清晰的看到A::max()的符號是U,即undefined,所以,它希望鏈結器去其它的地方找到函式的定義。若是一切正常的話,那麼我們還有乙個A.

cpp,然後生成乙個a.o,鏈結器去a.o的地方就可以找到這個函式定義了。

然而我們去編譯其實現檔案檢視其符號表:

我們可以發現,是沒有這個符號表的,因為如前文所述,inline函式並不會生成函式呼叫,會就在本原始檔中展開,於是也就沒有了函式的符號。

那麼正是如此,後面鏈結器,把產生的.o合併到一起的時候,A::max()依然是未定義的,如下圖所示:

那麼,若是非內聯的情況呢?

我們可以發現,a.o就會產生A::max()的函式符號,這樣的話,若鏈結器去鏈結main.o a.o :

我們就會發現main.o 帶U標記的undefined的A::max()被尋找到了,並在最後的.o中進行了填充。

那麼,為什麼inline的函式定義放在標頭檔案就可以呢?因為我們使用的時候,會#include "a.h",那麼這個時候編譯器首先會預處理展開,這樣也就包括了A::

max()的定義,使用g++ -E http://

a.cc

> a.i; vim a.i 後如下圖所示:

那麼這個時候,http://

main.cc

在本原始檔就可以找到A::max()的定義了,然後讓我們看最後的符號表:

也的確如我們意想的不是U的undefined。

那麼,這裡多提一句的是,在現代的C++編譯器中,我們幾乎都做乙個優化叫做內聯函式優化,因為我們在優化的時候,若不是IPA這樣的都是以乙個函式來進行,那麼我們內聯函式優化後就會把相關的定義展開在乙個函式中,這樣就可以進行更好的優化。而這個內聯函式的優化級別,在每乙個編譯器中是不同的,但是在我們實際C++編譯器的實現中,其實已經完全不是很多教科書提到的幾行了,我們往往是100行,乃至更多行的函式都會內聯展開,就是為了更好的優化。而我們內聯優化的話,其實也就是根據你的函式是多少行來進行決定的,於是在現代C++編譯器中,如果你是為了inline優化而加上inline的話,我認為inline的意義在這裡已經完全不需要了,現代的C++編譯器優化已經非常強悍了。

所以,若將來inline被C++廢棄,也是完全可以理解的。

C 中的constexpr函式有什麼作用?

C十十20年 新標準不是這樣描述的,參見 C 程式設計精要教程 介紹的2017標準,primer好像是2011標準。其實質含義是,當呼叫該函式用常量作為實參時,編譯程式應盡量根據函式體計算出其返回值,該值若在編譯時能計算出來,它也是乙個作為返回值的常量。因此,這樣的函式和呼叫可被優化掉,而不存在於編...

巨集函式相較於內聯函式是否毫無優勢?

傳統的幻想書屋 巨集可以用作強制內聯,要知道現在的inline已經變成乙個對於要求函式內聯來說有沒有都沒關係的關鍵字了,因為不管你寫不寫,編譯器都有權決定你這個函式要不要inline,但是巨集卻可以保證inline,像有的記憶體很小的平台,就經常這麼幹。當然對於c 來說,能不用就不用,畢竟巨集沒有任...

C 虛函式和C 虛函式的區別?

c 不了解。但是關於c 的說法,這樣是不對的。題主你其實糾結的不是語言,而是an implementation of c 意思是,之所以會有上面的結果,是因為你的編譯器的實現。在c 標準裡面,對於virtual 的具體實現沒有做任何要求。而virtual method table只是大多數編譯器的實...