內聯在多個原始檔中使用的函式

對於經常呼叫的小函式,與函式呼叫相關的開銷可能是該函式總執行時間的很大一部分。因此,提高效能的一種方法是消除開銷。

在這個例子中,我們在三個原始檔中使用了四個函式(加上 main())。其中兩個(plusfive()timestwo())分別由位於“source1.c”和“source2.c”中的另外兩個呼叫。包含了 main(),因此我們有一個工作示例。

main.c 中:

#include <stdio.h>
#include <stdlib.h>
#include "headerfile.h"

int main(void) {
    int start = 3;
    int intermediate = complicated1(start);
    printf("First result is %d\n", intermediate);
    intermediate = complicated2(start);
    printf("Second result is %d\n", intermediate);
    return 0;
}

source1.c:

#include <stdio.h>
#include <stdlib.h>
#include "headerfile.h"

int complicated1(int input) {
    int tmp = timestwo(input);
    tmp = plusfive(tmp);
    return tmp;
}

source2.c:

#include <stdio.h>
#include <stdlib.h>
#include "headerfile.h"

int complicated2(int input) {
    int tmp = plusfive(input);
    tmp = timestwo(tmp);
    return tmp;
}

headerfile.h:

#ifndef HEADERFILE_H
#define HEADERFILE_H

int complicated1(int input);
int complicated2(int input);

inline int timestwo(int input) {
  return input * 2;
}
inline int plusfive(int input) {
  return input + 5;
}

#endif

函式 timestwoplusfivecomplicated1complicated2 呼叫,它們位於不同的翻譯單元或原始檔中。為了以這種方式使用它們,我們必須在標題中定義它們。

像這樣編譯,假設 gcc:

cc -O2 -std=c99 -c -o main.o main.c
cc -O2 -std=c99 -c -o source1.o source1.c
cc -O2 -std=c99 -c -o source2.o source2.c
cc main.o source1.o source2.o -o main

我們使用 -O2 優化選項,因為某些編譯器在沒有啟用優化的情況下不會內聯。

inline 關鍵字的作用是所討論的函式符號不會傳送到目標檔案中。否則,在最後一行會發生錯誤,我們將連結目標檔案以形成最終的可執行檔案。如果我們沒有 inline,則會在 .o 檔案中定義相同的符號,並且會出現多重定義的符號錯誤。

在實際需要符號的情況下,這具有根本不產生符號的缺點。處理這種情況有兩種可能性。第一種是在 .c 檔案中新增一個額外的 extern 行內函數宣告。所以將以下內容新增到 source1.c

extern int timestwo(int input);
extern int plusfive(int input);

另一種可能性是使用 static inline 而不是 inline 來定義函式。該方法的缺點是最終可能在使用該頭生成的每個目標檔案中產生所討論的函式的副本。