Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki



Teraz jest 1 lut 2026, o 17:29


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 10 ] 
Autor Wiadomość
 Tytuł: static funkcje
PostNapisane: 22 lut 2018, o 20:23 
Offline
Użytkownik

Dołączył(a): 13 lis 2016
Posty: 35
Pomógł: 0

Witam,
mam pytanie które mnie nurtuje od jakiegoś czasu i dotyczy użycia słówka static w związku z funkcjami. Rozumiem, że celem takiego użycia jest swego rodzaju hermetyzacja. Funkcji takiej nie umieszczamy w pliku nagłówkowym(*.h), ponieważ nie udostępniamy jej zewnętrznym innym plikom(*.c). Użycie takiego przydomka dla funkcji jest zasadne tylko w pliku (*.c), w którym funkcje takie są wykorzystywane przez np. funkcje udostępniane przez plik nagłówkowy. Jednak tutaj pojawia się moje pytanie:

Skoro funkcji takiej nie deklarujemy w pliku nagłówkowym, to jaki jest sens użycia static do funkcji w pliku (*.c)? Funkcja taka jest i tak niewidoczna dla innych plików, ponieważ jej deklaracja nie znajduje się w pliku nagłówkowym? Wiem, że jakiś sens tego być musi więc czego nie wiem, albo gdzie robię błąd ?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 22 lut 2018, o 20:27 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 27449
Lokalizacja: Szczecin
Pomógł: 1045

BarGai napisał(a):
Funkcja taka jest i tak niewidoczna dla innych plików, ponieważ jej deklaracja nie znajduje się w pliku nagłówkowym? Wiem, że jakiś sens tego być musi więc czego nie wiem, albo gdzie robię błąd ?

Widzisz pan kompilatory są sprytne i nawet jeśli nie będzie nagłówka w pliku *.h to on spróbuje podstawić funkcję o tej samej nazwie ... wprawdzie pokaże warning że nie wie czy dobrze robi ale spróbuje. Gdy zaś funkcja będzie miała specyfikator static to nie będzie próbował ;)

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 22 lut 2018, o 21:04 
Offline
Użytkownik

Dołączył(a): 13 lis 2016
Posty: 35
Pomógł: 0

Może na przykładzie, bo chyba rozumiem co chce mi Pan przekazać, ale mam jeszcze trochę wątpliwości. Trzy pliki: main.c, file1.c, file1.h, dwie funkcje fun1(), fun2(). Do main.c i file1.c dołączam plik nagłówkowy file1.h. W file1.c znajduje się deklaracja i definicja fun1() jako funkcji statycznej. W file1.c znajduje się definicja, a w file1.h deklaracja fun2() jako funkcji "zwykłej". W main.c wywołujemy fun1() i fun2(). Rezultat: wywołanie fun1() zgłasza błąd(brak definicji fun1()), fun2() realizuje ciało funkcji. Teraz z file1.h usuwamy deklarację fun2() i dopisujemy o ile potrzebne deklarację w file1.c. Podobnie w main.c wywołujemy te dwie funkcje z tym, że teraz fun2() wywołuje się z warningiem, a fun1() analogicznie jak poprzednio.

To jest to sprytne podstawienie przez kompilator funkcji mimo braku jej deklaracji w dołączonym pliku nagłowkowym ?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 22 lut 2018, o 21:53 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 27449
Lokalizacja: Szczecin
Pomógł: 1045

oczekujesz cudów gdy nie ma deklaracji funkcji ? ;)

poza tym static powoduje całkowicie inne podejście do optymalizacji i funkcje takie mogą być czasem potraktowane jako inline

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 22 lut 2018, o 22:02 
Offline
Użytkownik

Dołączył(a): 13 lis 2016
Posty: 35
Pomógł: 0

No właśnie dlatego miałem obawy, czy dobrze zrozumiałem i na to wychodzi, że zle zrozumiałem ;)
mirekk36 napisał(a):
to on spróbuje podstawić funkcję o tej samej nazwie

Czyli jaką funkcję o tej samej nazwie jeśli nie taką, która jest zdefiniowana w innym pliku *.c?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 22 lut 2018, o 22:13 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 27449
Lokalizacja: Szczecin
Pomógł: 1045

BarGai napisał(a):
No właśnie dlatego miałem obawy, czy dobrze zrozumiałem i na to wychodzi, że zle zrozumiałem ;)
mirekk36 napisał(a):
to on spróbuje podstawić funkcję o tej samej nazwie

Czyli jaką funkcję o tej samej nazwie jeśli nie taką, która jest zdefiniowana w innym pliku *.c?

sory ale kompletnie nie wiem co ty kombinujesz ;)

no zrób że sobie prosty test - użyj funkcji _delay_ms() ale nie dodawaj pliku nagłówkowego, skompiluj program , zobacz jaki masz warning, weź translate.google.pl i przetłumcza sobie a poźniej zapytaj czego nie rozumiesz

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 22 lut 2018, o 23:23 
Offline
Użytkownik

Dołączył(a): 13 lis 2016
Posty: 35
Pomógł: 0

Może zbyt daleko zabrnąłem w swoich rozważaniach. Może inaczej. Mam funkcję statyczna w pliku d_lcd.c.
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
Teraz usuwam z niej słówko static. Tak jak napisałem w pierwszym poście, nie potrafię zauważyć różnicy bo ta funkcja nie jest zadeklarowana w d_lcd.h. Napisał Pan, że kompilator spróbuje podstawić funkcję w takim przypadku i zglosi warning jednak w moim przypadku tego nie widzę.

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Poniżej tego fragmentu znajdują się definicje między innymi powyższych funkcji.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 23 lut 2018, o 00:32 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 27449
Lokalizacja: Szczecin
Pomógł: 1045

ależ ty mieszasz chłopie ;) ... aż strach

skoro dajesz funkcji specyfikator static to po jakiego grzyba wstawiasz ten nagłówek i to jeszcze ze static a na dodatek inline do pliku *.H

na prawdę nie czaję bazy ;) ... groch z kapustą .... zaczynasz od static a później się okazuje że masz jeszcze inline a na końcu okaże się coś jeszcze innego

Może najpierw postaraj się zrozumieć chociaż jeden specyfikator i jak działa - zamiast strzelać wszystkimi jakie tylko znasz i jakie ci ślina na język przyniesie

nawet nie umiem pomóc bo nie wiem co ty tworzysz i w co brniesz

a ileż można powtarzać to samo, że jak dajesz specyfikator static to nie umieszczasz nagłówka funkcji w pliku *.h ... czy to jest trudne do zapamiętania ?

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 23 lut 2018, o 10:22 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 15 lut 2017
Posty: 368
Lokalizacja: Gliwice
Pomógł: 34

BarGai napisał(a):
Teraz usuwam z niej słówko static. Tak jak napisałem w pierwszym poście, nie potrafię zauważyć różnicy

Chyba wiem o co Koledze chodzi.
Brak różnic pewnie wynika z opcji kompilacji, niestety nie jestem na tyle biegły, żeby wskazać o które opcje chodzi.
Natomiast pewne jest, że jeśli zdefiniujesz jakąś funkcję z opcją static i nie wykorzystasz jej, to dostaniesz ostrzeżenie od kompilatora:
"warning: 'temp_func' defined but not used [-Wunused-function]".

Gdzie istotna jest tutaj opcja kompilatora "-Wunused-function", która dba o optymalizację miejsca na kod programu.

To wydaje się oczywiste, że kompilator dba o to by nie "zaśmiecać" pamięci programu funkcjami niepotrzebnymi, w ten sposób zaoszczędzimy miejsce w pamięci flash.
Jeśli usuniesz "static" to powyższego ostrzeżenia nie dostaniesz i niepotrzebną funkcję umieścisz w pamięci programu.
Ten rodzaj optymalizacji jest wg mnie bardzo pożądany.

A teraz najciekawsze. Początkującym najczęściej się wydaje, że jeśli zrobią definicję funkcji np w pliku plik_temp.c to deklaracja funkcji musi być koniecznie w pliku plik_temp.h.
Nic bardziej mylnego, deklarację można zrobić równie dobrze w pliku main.c, czy jeszcze zupełnie innym, nagłówkowym czy też źródłowym.
Oczywiście miejsce deklaracji musi mieć uzasadnienie. Jeśli pojawi się w main.c to jedynym modułem, gdzie można użyć funkcji będzie main.o
Jeśli deklarację wrzucimy do jakiegoś innego pliku nagłówkowego .h to funkcji będzie można użyć wszędzie tam gdzie zostanie zainkludowana te plik nagłówkowy.

Tu pewnie się mylę, ale wg mnie deklaracja funkcji jest głównie potrzebna linkerowi i mówi, że "gdzieś" w modułach znajduje się funkcja o tej konkretnej nazwie.

Przedrostek static pozwala na tworzenie wielu funkcji o tych samych nazwach w wielu modułach. Wynika to wg mnie z bardzo dużej elastyczności języka C, ale czasami może wprowadzać w konsternację programistę, więc chyba raczej nie powinno się z tego korzystać.

Jeśli pojawi się gdzieś deklaracja funkcji o tej samej nazwie, to ona nie będzie "wskazywać" na żadną funkcję w pamięci programu, bo wszystkie będą static, ale wystarczy, że tylko z jednej z nich usuniemy static to właśnie ta będzie mogła być widziana przez inne moduły.

Jeśli tylko w modułach pojawią się co najmniej dwie te same nazwy funkcji, bez static to zaraz otrzymamy błąd:
"multiple definition of " i to wykryje linker.

A jeszcze jedna ciekawa cecha przychodzi mi do głowy.
Jeśli w dowolnym module zdefiniujesz funkcję to wcale jej deklaracji nie musisz umieszczać w pliku nagłówkowym.
Wystarczy, że w dowolnym pliku źródłowym, przed wywołaniem tej funkcji, umieścisz jej deklarację.
Tych deklaracji możesz robić wiele, praktycznie w każdym pliku źródłowym, tam gdzie interesuje cię wywołanie tej funkcji.
Takie działanie jest oczywiste, w końcu "include" kopiuje całe pliki nagłówkowe i umieszcza je tam gdzie następuje wywołanie tej dyrektywy.

Po prostu deklaracja to tak jakby "wskaźnik", że ciało funkcji jest "gdzieś" dostępne, a poprawnym wskazaniem zajmuje się właśnie linker.


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 23 lut 2018, o 10:47 
Offline
Użytkownik

Dołączył(a): 13 lis 2016
Posty: 35
Pomógł: 0

mirekk36 napisał(a):
skoro dajesz funkcji specyfikator static to po jakiego grzyba wstawiasz ten nagłówek i to jeszcze ze static a na dodatek inline do pliku *.H

Ależ skąd Pan wywnioskował, że wstawiam go do pliku *.h? Przecież ja nic o tym nie wspominałem, broń boże w żadnym razie tego nie robiłem. W pierwszym poście napisałem:
BarGai napisał(a):
Rozumiem, że celem takiego użycia jest swego rodzaju hermetyzacja. Funkcji takiej nie umieszczamy w pliku nagłówkowym(*.h), ponieważ nie udostępniamy jej zewnętrznym innym plikom(*.c). Użycie takiego przydomka dla funkcji jest zasadne tylko w pliku (*.c), w którym funkcje takie są wykorzystywane przez np. funkcje udostępniane przez plik nagłówkowy.

Poniżej znajduje się fragment pliku d_lcd.c, jest to fragment biblioteki dla wyswietlacza LCD. W dołączonym pliku "d_lcd.h" nie ma żadnej deklaracji poniższych funkcji. W pliku "d_lcd.h" znajduja się tylko inne udostępniane na zewnątrz funkcje do wyświetlacza lcd.
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


W związku z tym, jeśli w pliku d_lcd.c(fragment powyzej) wymażemy przydomek static dla funkcji( da to nam w efekcie "zwykłą" funkcję np. void d_lcd_dir_out(void)) i w d_lcd.h nie będzie deklaracji tej funkcji to funkcja ta i tak nie będzie udostępniona poprzez dołączenie pliku d_lcd.h do innych plików bo nie ma w nim tak czy siak żadnej deklaracji funkcji. Stąd nie rozumiem użycia static w takim przypadku bo tak czy inaczej swego rodzaju hermetyzacja będzie niezależnie, czy funkcja będzie w pliku *.c ze static czy nie, bo i tak nie ma jej deklaracji w udostępnianym pliku.

Przepraszam, ale czasem ciężko przedstawić to co ma czlowiek na mysli w piśmie ;) Rozumiem, że robię coś zle i ma to jakiś sens na pewno dlatego chcę to zrozumieć. Chyba po czasie po prostu to do mnie dojdzie i sam zrozumiem to o co mi chodzi. Wtedy ewentualnie napiszę jeśli nieumiejętnie przedstawiłem swój problem ;)

------------------------ [ Dodano po: 21 minutach ]

Zealota napisał(a):
Natomiast pewne jest, że jeśli zdefiniujesz jakąś funkcję z opcją static i nie wykorzystasz jej, to dostaniesz ostrzeżenie od kompilatora:
"warning: 'temp_func' defined but not used [-Wunused-function]".

Gdzie istotna jest tutaj opcja kompilatora "-Wunused-function", która dba o optymalizację miejsca na kod programu.

To wydaje się oczywiste, że kompilator dba o to by nie "zaśmiecać" pamięci programu funkcjami niepotrzebnymi, w ten sposób zaoszczędzimy miejsce w pamięci flash.
Jeśli usuniesz "static" to powyższego ostrzeżenia nie dostaniesz i niepotrzebną funkcję umieścisz w pamięci programu.
Ten rodzaj optymalizacji jest wg mnie bardzo pożądany.


TAK, TAK i jeszcze raz TAK !!! O to mi właśnie chodziło w moich rozważaniach, które może nieudolnie starałem się przedstawić. Teraz wydaje się być logicznym używanie przydomka static do funkcji. Dziękuję obu Panom za poświęcony czas, chęci i pomoc w rozwiązaniu problemu !!!



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
Wyświetl posty nie starsze niż:  Sortuj wg  
Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 10 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 1 gość


Nie możesz rozpoczynać nowych wątków
Nie możesz odpowiadać w wątkach
Nie możesz edytować swoich postów
Nie możesz usuwać swoich postów
Nie możesz dodawać załączników

Szukaj:
Skocz do:  
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO