Pytanie Powody używania funkcji statycznych i zmiennych w C


Zastanawiam się nad wykorzystaniem static słowo kluczowe jako ograniczenie zakresu dla zmiennych w pliku, w C.

Standardowy sposób budowania programu C, jak widzę, to:

  • mieć paczkę plików c definiujących funkcje i zmienne, ewentualnie ograniczone zasięgiem static.
  • ma kilka plików h deklarujących funkcje i ewentualnie zmienne odpowiadającego pliku c, dla innych plików c do użycia. Prywatne funkcje i zmienne nie są publikowane w pliku h.
  • każdy plik c jest kompilowany osobno do pliku o.
  • wszystkie pliki o są połączone z plikiem aplikacji.

Widzę dwa powody deklarowania gobala jako static, jeśli zmienna nie została mimo wszystko opublikowana w pliku h:

  • jeden jest dla czytelności. Poinformuj przyszłych czytelników, w tym ja, że ​​zmienna nie jest dostępna w żadnym innym pliku.
  • drugi polega na zapobieganiu redeclarowaniu zmiennej przez inny plik c jako extern. Przypuszczam, że linker nie chciałby, aby zmienna była jednocześnie extern i static. (Nie podoba mi się pomysł, aby plik redeclaring zmienną posiadaną przez kogoś innego jako extern, czy to jest w porządku?)

Każdy inny powód?

To samo dotyczy static Funkcje. Jeśli prototyp nie zostanie opublikowany w pliku h, inne pliki i tak nie będą mogły korzystać z tej funkcji, więc po co ją definiować static w ogóle? Widzę te same dwa powody, ale nie więcej.


23
2018-06-04 11:58


pochodzenie


Sześć lat później, teraz to wiem static nie ogranicza zakresu, daje wewnętrzne powiązania. Jest podobnie, jeśli uznaliby Państwo jednostkę tłumaczeniową za zakres, ale nie za poprawny termin. - Gauthier


Odpowiedzi:


Kiedy mówisz o informowaniu innych czytelników, rozważ sam kompilator jako czytelnik. Jeśli zadeklarowana jest zmienna static, które może wpływać na stopień, w jakim kopiują się optymalizacje.

Przedefiniowanie a static zmienna jako extern jest niemożliwe, ale kompilator (jak zwykle) da ci wystarczająco dużo liny, żeby się powiesić.

Jeśli piszę static int foo; w jednym pliku i int foo; winnym, są uważane za różne zmienne, pomimo tego samego imienia i typu - kompilator nie będzie narzekał, ale prawdopodobnie będziesz bardzo zdezorientowany, próbując później odczytać i / lub zdebugować kod. (Jeśli piszę extern int foo; w drugim przypadku nie uda się połączyć, chyba że zadeklaruję niestatyczność int foo; gdzieś indziej.)

Zmienne globalne rzadko pojawiają się w plikach nagłówkowych, ale gdy tak się stanie, powinny zostać zadeklarowane extern. Jeśli nie, w zależności od kompilatora, ryzykujesz, że każdy plik źródłowy, który zawiera ten nagłówek, zadeklaruje swoją własną kopię zmiennej: w najlepszym wypadku spowoduje to awarię łącza (symbol wielokrotnie mnożnikowy), aw najgorszym przypadku kilka mylących przypadków zacienienia.


25
2018-06-04 12:20



Ciekawy. Rozumiem, że ten "zewnętrzny plik globalny w pliku nagłówkowym" nadal potrzebuje definicji w pliku c, ponieważ plik zewnętrzny w pliku h powoduje, że jest to zwykła deklaracja. - Gauthier
Masz rację. - crazyscot


Deklarując zmienną static na poziomie pliku (static w ramach funkcji ma inne znaczenie) zabraniasz innym jednostkom dostępu do niej, np. jeśli spróbujesz użyć zmiennej wewnątrz innej jednostki (zadeklarowanej przy pomocy extern), linker nie znajdzie tego symbolu.


8
2018-06-04 12:04



Jest to dokładnie jeden z dwóch powodów, o których wspomniałem: "Drugim jest uniemożliwienie innemu plikowi c korzystania z globalnego ograniczenia, na pozór ograniczonego przez redeclaring go jako extern"I zastanawiałem się nad jakością takiej praktyki? - Gauthier
@Gaunthier Więc twój post ma wewnętrzny konflikt - qrdl
IMO, static ma to samo znaczenie we wszystkich trzech dobrze znanych zastosowaniach (zmienna pliku, zmienna funkcji, funkcja) i to jest: "ma ograniczony zakres i ma stały adres w trakcie wykonywania programu". - Gauthier
W tym sensie znaczenie jest takie samo, ale cel jest inny - static na poziomie pliku kontroluje widoczność, static na poziomie funkcji kontrola poziomu. - qrdl
Jeśli zadeklarujesz coś statycznego w jednej jednostce kompilacji, nie możesz redeclare go jako zewnętrznego w innej jednostce kompilacji. Będą postrzegane jako różne rzeczy. static służy również do zapobiegania zanieczyszczaniu przestrzeni nazw - np. możesz mieć 2 jednostki kompilacji zawierające funkcję o nazwie sort i będą traktowane jako różne rzeczy. - nos


Kiedy deklarujesz statyczny funkcja wywołanie funkcji jest "bliskie połączenie" i teoretycznie działa lepiej niż "dalekie połączenie". Możesz google uzyskać więcej informacji. To jest to, co znalazłem za pomocą prostego wyszukiwania google.


6
2018-06-04 13:07



Również interesujące, choć zależne od platformy (mój cel ma tylko jedną instrukcję CALL do absolutnego i nie daleko / blisko). - Gauthier
na przykład gcc może zmienić konwencję wywołania (na coś szybciej) dla funkcji statycznych na wielu platformach. - nos


Jeśli zmienna globalna zostanie zadeklarowana jako statyczna, kompilator może czasami dokonać lepszej optymalizacji, niż gdyby nie była. Ponieważ kompilator wie, że do zmiennej nie można uzyskać dostępu z innych plików źródłowych, może lepiej wycenić działanie kodu (np. "Ta funkcja nie modyfikuje tej zmiennej"), co może czasem powodować szybsze generowanie kodu. Bardzo niewiele kompilatorów / łączników może dokonywać tego rodzaju optymalizacji w różnych jednostkach tłumaczeniowych.


1
2018-06-04 12:19





Jeśli zadeklarujesz zmienną foo w pliku ac bez uczynienia jej statyczną, oraz zmienną foo w pliku bc bez uczynienia jej statyczną, obie są automatycznie zewnętrzne, co oznacza, że ​​linker może narzekać, jeśli zainicjujesz oba i przypisze tę samą lokalizację pamięci, jeśli to zrobi. narzekać. Spodziewaj się dobrej debugowania kodu.

Jeśli napiszesz funkcję foo () w pliku ac bez uczynienia jej statyczną, oraz funkcję foo () w pliku bc bez uczynienia jej statyczną, linker może narzekać, ale jeśli nie, wszystkie wywołania foo () będą wywoływać ta sama funkcja. Spodziewaj się dobrej debugowania kodu.


0
2018-04-01 06:58





Moim ulubionym użyciem statycznego jest możliwość przechowywania metod, które nie będę musiał Injectować lub tworzyć obiektów do użycia, tak jak to widzę. Prywatne metody statyczne są zawsze użyteczne, gdzie publiczne statyczne trzeba poświęcić więcej czasu na myślenie z tego, co robisz, aby uniknąć tego, co zdefiniowano w crazyscot, zabraniając sobie zbyt wiele lin i przypadkowo wieszając siebie!

Lubię przechowywać folder dla klas Helperów dla większości moich projektów, które składają się głównie ze statycznych metod robienia rzeczy szybko i sprawnie w locie, bez obiektów potrzebnych!


-1
2018-06-04 13:51



Pytanie dotyczy C, nie C ++. W C nie ma klas, żadnych metod ani prywatnych członków. Ponadto w C ++ występuje różnica w funkcjach statycznych i metodach statycznych. - el.pescado
Ups! Zdaję sobie sprawę, że zdecydowanie błędnie przeczytałem pytanie. - Jake Kalstad