Wiele projektów C++ (np. Wiele bibliotek Boost
) jest "połączonych tylko z nagłówkiem".Łączenie tylko nagłówków
Czy jest to również możliwe w przypadku zwykłego C
? Jak umieścić kod źródłowy w nagłówkach? Czy są jakieś strony na ten temat?
Wiele projektów C++ (np. Wiele bibliotek Boost
) jest "połączonych tylko z nagłówkiem".Łączenie tylko nagłówków
Czy jest to również możliwe w przypadku zwykłego C
? Jak umieścić kod źródłowy w nagłówkach? Czy są jakieś strony na ten temat?
Streszczenie: Możesz, ale nie powinieneś.
C i C++ kod jest preprocesowany zanim zostanie skompilowany: wszystkie nagłówki są „wklejone” w plikach źródłowych, które je zawierają, rekurencyjnie. Jeśli zdefiniujesz funkcję w nagłówku i zostanie ona dołączona do dwóch plików C, otrzymasz dwie kopie w każdym pliku obiektów (naruszenie One Definition Rule).
Możesz tworzyć biblioteki C tylko z nagłówkiem, jeśli wszystkie twoje funkcje są oznaczone jako static
, czyli niewidoczne poza jednostką tłumaczeniową. Ale oznacza to również, że otrzymasz kopię wszystkich funkcji statycznych w każdej jednostce tłumaczeniowej, która zawiera plik nagłówkowy.
W C++ jest nieco inaczej: funkcje inline nie są static
, symbole emitowane przez kompilator są nadal widoczne przez linker, ale linker może odrzucić duplikaty zamiast rezygnować ("słabe" symbole).
Zapisywanie kodu C w nagłówkach nie jest idiotyczne, chyba że jest oparte na makrach (na przykład queue(3)
). W C++ głównym powodem do zachowania kodu w nagłówkach są szablony, które mogą powodować tworzenie kodu dla różnych parametrów szablonu, co nie ma zastosowania do C.
+1: Obejmuje prawie wszystkie podstawy, które myślę. –
Nie łączysz nagłówków.
W C++ nieco łatwiej jest napisać kod, który jest już lepszy w nagłówkach niż w osobno skompilowanych modułach, ponieważ szablony tego wymagają.
Ale można również użyć słowa kluczowego inline
dla funkcji, które istnieją zarówno w języku C, jak i C++.
// Won't cause redefinition link errors, because of 6.7.4/5
inline void foo(void) {
// ...
}
[c99: 6.7.4/5:]
Funkcja zadeklarowanąinline
funkcji specyfikacją jest funkcją rolki. Detektor funkcji może pojawić się więcej niż jeden raz; zachowanie jest takie samo, jak gdyby pojawiło się tylko raz. Wykonywanie funkcji inline sugeruje, że połączenia z funkcją powinny przebiegać tak szybko, jak to możliwe. Zakres, w jakim takie sugestie są skuteczne, jest zdefiniowany przez implementację.
Trochę utkniesz, jeśli chodzi o obiekty danych.
- W pewnym sensie.
- C99 na pewno. C89/C90 Muszę sprawdzić.
Czy chodziło Ci o statyczne słowo kluczowe? Ponieważ inline jest tylko poleceniem dla kompilatora i może być całkowicie zignorowane. – Cartesius00
@ James: Nie, miałem na myśli 'inline'. Chociaż 'inline' jest tylko podpowiedzią i kompilator nie musi fizycznie wstawiać funkcji, efekt, który ma on na powiązaniu funkcji, jest dobrze zdefiniowany i musi być obserwowany przez implementację. W przeciwnym razie, jak mógłbyś kiedykolwiek powiedzieć jakie powiązanie ma twoja funkcja 'inline'? –
Och, widzę, jest inaczej w C kontra C++, prawda? – Cartesius00
doładowania sprawia, szablony intensywnego użytkowania i szablon meta-programowania, który nie może emulować (wszystkie, które łatwo) w C.
Ale można oczywiście oszukać poprzez deklaracje i kod w nagłówkach C którego #include
ale to nie to samo. Powiedziałbym, "Kiedy w Rzymie ..." i program C zgodnie z konwencjami C z bibliotekami.
Uważam, że "Kiedy w Rzymie ..." to świetna odpowiedź. Dziękuję :) – Cartesius00
Cieszę się, że mogę pomóc. Możesz go również zaakceptować, pod warunkiem, że nadal będzie to najlepsza odpowiedź podczas sprawdzania. –
Tak, jest całkiem możliwe. Deklaruj wszystkie funkcje w nagłówkach i wszystkie jako static
lub po prostu użyj pojedynczej jednostki kompilacji (tj. Tylko jednego pliku c) w swoich projektach.
Jako osobistą anegdotę znam wielu fizyków, którzy upierają się, że ta technika jest jedyną prawdziwą metodą programowania C. Jest to korzystne, ponieważ jest to wersja biednego mężczyzny z -fwhole-program
, tj. Dokonuje optymalizacji w oparciu o wiedzę możliwe zachowanie funkcji. Jest to praktyczne, ponieważ nie musisz uczyć się o używaniu flag łącznika. To zły pomysł, ponieważ cały twój program musi być skompilowany jako całość i ponownie skompilowany z każdą drobną zmianą.
Osobiście, poleciłbym go lub przynajmniej skorzystam z static
tylko dla kilku funkcji.
Odpowiedź nie wskazuje na rażącą dziurę w tym podejściu. –
@ TomalakGeret'kal: Które z jaskrawych dziur? – thiton
'statyczny' daje ci kopie na TU. Naprawdę, dziury, o których wspominają wszystkie inne odpowiedzi. –
Robisz to dokładnie tak samo, jak w C++. Włączenie nagłówka jest funkcją preprocesora C. – avakar
Ale masz wszystkie te funkcje statyczne i funkcje publiczne, myślę, że to nie takie proste. – Cartesius00