C Language
Inlining
Szukaj…
Funkcje wstawiania używane w więcej niż jednym pliku źródłowym
W przypadku małych funkcji, które są często wywoływane, narzut związany z wywołaniem funkcji może stanowić znaczną część całkowitego czasu wykonywania tej funkcji. Jednym ze sposobów poprawy wydajności jest wyeliminowanie kosztów ogólnych.
W tym przykładzie używamy czterech funkcji (plus main()
) w trzech plikach źródłowych. Dwa z nich ( plusfive()
i timestwo()
) są wywoływane przez pozostałe dwa znajdujące się w „source1.c” i „source2.c”. Zawiera main()
więc mamy działający przykład.
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;
}
plik nagłówka.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
Funkcje timestwo
i plusfive
są wywoływane zarówno przez complicated1
jak i complicated2
, które znajdują się w różnych „jednostkach tłumaczeniowych” lub plikach źródłowych. Aby użyć ich w ten sposób, musimy zdefiniować je w nagłówku.
Skompiluj w ten sposób, zakładając 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
Używamy opcji optymalizacji -O2, ponieważ niektóre kompilatory nie są wbudowane bez włączonej optymalizacji.
Efekt inline
słowo kluczowe jest to, że symbol funkcji w pytaniu nie jest emitowane do pliku wynikowego. W przeciwnym razie wystąpiłby błąd w ostatnim wierszu, w którym łączymy pliki obiektów w celu utworzenia końcowego pliku wykonywalnego. Gdybyśmy nie mieli inline
, ten sam symbol byłby zdefiniowany w obu plikach .o
, i wystąpiłby błąd „wielokrotnie zdefiniowanego symbolu”.
W sytuacjach, w których symbol jest rzeczywiście potrzebny, ma to tę wadę, że symbol wcale nie jest wytwarzany. Istnieją dwie możliwości poradzenia sobie z tym. Pierwszym z nich jest dodanie dodatkowej deklaracji extern
funkcji wstawianych w dokładnie jednym z plików .c
. Dodaj więc następujący source1.c
do source1.c
:
extern int timestwo(int input);
extern int plusfive(int input);
Inną możliwością jest zdefiniowanie funkcji za pomocą static inline
zamiast inline
. Ta metoda ma tę wadę, że ostatecznie kopia danej funkcji może zostać utworzona w każdym pliku obiektowym utworzonym przy użyciu tego nagłówka.