2015-12-07 19 views
5

Próbowałem wyszukać dobrą odpowiedź w Internecie, ale nie udało mi się uzyskać takiej, którą mogę w pełni zrozumieć. Załóżmy, że mam nagłówka "add.h":Funkcja Inline w pliku nagłówkowym w C

inline int add(int a, int b){ return a+b; } 

plik o nazwie "adddouble.c":

#include "add.h" 

int adddouble(int a, int b){ return 2*add(a,b); } 

plik o nazwie "addsquare.c":

#include "add.h" 

int addsquare(int a, int b){ return add(a,b)*add(a,b); } 

Główny plik "main.c":

#include<stdio.h> 

int adddouble(int, int); 
int addsquare(int, int); 
int main(){ 
printf("add double = %d\n", adddouble(10,20)); 
printf("add square = %d\n", addsquare(10,20)); 
return 0; 
} 

Używam gcc5.2.0 do kompilowania tych plików, ale otrzymałem: "Niezdefiniowane symbole dla architektury x86_64:". Jeśli dodaję statyczne do funkcji inline w add.h lub dodaj deklarację "extern int add (int, int);" do "adddouble.c", pomyślnie kompiluje bez błędów. Jestem nowy w funkcji inline, nie wiem jak wyjaśnić i zrozumieć to zachowanie. Dzięki

+1

Jakie są Twoje opcje kompilacji? Dopóki nie zbudujesz C99 lub C11, nie ma koncepcji funkcji inline w C. – StoryTeller

+0

Musisz skompilować plik nagłówkowy z innymi plikami c lub dostarczyć zarówno .h jak i .c, add.h dla prototypu dodawania i Dodaj.c dla kodu – qleguennec

+0

+1 Dobre pytanie. Właściwie łączy się dobrze z g ++, ale nie mogę go uruchomić z gcc (-std = c11). Te symbole dodawania są niezdefiniowane (U) w obu addquare.o i adddouble.c. g ++ zamiast tego tworzy słabe symbole (W) dla funkcji dodawania i dlatego to łączy. – PSkocik

Odpowiedz

6

Według http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf, to wygląda inline funkcje zachowują się różnie w C i C++:

Każda funkcja z wewnętrznym wiązaniem może być funkcja inline. W przypadku funkcji z łączem zewnętrznym obowiązują następujące ograniczenia: Jeśli funkcja jest zadeklarowana ze specyfikatorem funkcji wbudowanej, to musi również być zdefiniowana w tej samej jednostce tłumaczeniowej. Jeśli wszystkie zakresy deklaracji zakresu dla funkcji w jednostce tłumaczeniowej zawierają wbudowany specyfikator funkcji bez obiektu zewnętrznego, definicja w tej jednostce tłumaczeniowej jest definicją śródliniową. Definicja wbudowana nie zapewnia zewnętrznej definicji funkcji i nie zabrania zewnętrznej definicji w innej jednostce tłumaczeniowej. Definicja wbudowana stanowi alternatywę dla zewnętrznej definicji, którą tłumacz może zastosować do wykonania dowolnego wywołania funkcji w tej samej jednostce tłumaczeniowej. Nie jest określone, czy wywołanie funkcji używa definicji wbudowanej lub definicji zewnętrznej. 140)

Jeśli nie wstawisz tam static, definiujesz funkcję inline z zewnętrznym powiązaniem bez tworzenia instancji zewnętrznej definicji.

extern int add(int, int); instatiates definicję zewnętrznego dla tej funkcji, i trzeba to zrobić tylko raz (nie ma znaczenia, w którym plik) za powiązanie sukces (lub można zaznaczyć funkcję inline static i problem znika).

(W C++ inline tworzy słabych definicje zewnętrznych w każdej jednostce tłumaczeniowej, dzięki czemu nie trzeba się martwić o oznakowanie rzeczy static lub instancji dokładnie jedną zewnętrzną definicję funkcji inline - g ++ powinien wprost skompilować go z for f in *.c; do g++ -c "$f"; done; g++ *.o bez żadnych problemów.)

Powiązane problemy