内联在多个源文件中使用的函数

对于经常调用的小函数,与函数调用相关的开销可能是该函数总执行时间的很大一部分。因此,提高性能的一种方法是消除开销。

在这个例子中,我们在三个源文件中使用了四个函数(加上 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 来定义函数。该方法的缺点是最终可能在使用该头生成的每个目标文件中产生所讨论的函数的副本。