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.



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow