Marhef napisał(a):
Czyli co, obiekt, który nie został zdefiniowany w tym pliku? Czy źle zrozumiałem?
Natomiast znaczenie symbolu *COM*:
Cytuj:
SHN_COMMON Symbols defined relative to this section are common symbols, such as FORTRAN COMMON or unallocated C external variables.
Czyli? Zewnętrzna zmienna bez alokacji pamięci?
DOBRZE zrozumiałeś
No to teraz dla kolegi
roske - nieco ŁOPATOLOGICZNIE ale jeśli ktoś chce zrozumieć naprawdę jakiego okrutnego BABOLA sobie roske wymyślił i na tej bazie wysnuł teorię na temat zmiennych globalnych języka C ... zresztą podobnie jak kolega kisiel .... Obydwaj nie rozumieją jak mi się wydaje z jednej strony co to znaczy zakres widoczności / przykrywanie nazw ... i zamiast sprawdzić swoje teorie porządnie to łapią się za jakiś wymyślony i kompletnie ŹLE napisany KOD i na tej podstawie "bo coś im zadziałało" wyjasniają teorie świata podkładając pod to angielskie okreslenia - których nie potrafią przełożyć na język polski ale to nic - nie rozumiem co to znaczy ale pewnie to wyjaśnia tajemnicze zjawisko.
Czekałem kolego roske - kiedy dojdziesz do opisu swojego przypadku - i w zasadzie po twoich zadętych postach gdzie piszesz np:
roske napisał(a):
Co Cię tak dotknęło? Fakt, że wiedza, którą pozyskałeś jest fałszywa, czy to że ktoś Ci to uświadomił?
to aż się dyskutować z takim osobnikiem nie chce - ale ...
ale w sumie i dobrze, że temat powstał - więc postaram się wyjaśnić jak ja to widzę a inni niech sami wyciągną wnioski
Proszę bardzo - zgodnie z oczekiwaniami kolegi roske robieramy jego przykład na czynniki proste, że tak powiem
roske - przygotuj się.
Kolega tak mocno chciał żeby sobie każdy skompilował i zobaczył a później pisał że nikt nie skompilował - mając wszystkich za .... (szkoda gadać)
co widzimy na tym, jakże cudownym obrazku - otóż PIERWSZY przykładowy (skopany wg mnie) kod kolegi roske. Dlaczego skopany ? Proszę spojrzeć na tę czerwoną dwustronną przerywaną strzałkę. Tu kolega roske odstawia MEGA BONANZĘ
... otóż w ramach jednego projektu DEFINIUJE dwie zmienne o takiej samej nazwie. (Podobnie jak kolega kisiel - widać, że nie rozumie co to jest DEFINICJA zmiennej) ... no i BACH! ... kompilator mu nie krzyczy, czyli "łyknął" jak to mawiał klasyk kisiel. WSZYSTKO NIBY DZIAŁA ... prawda - co więcej roske zaczyna karkołomne próby wyjaśnień dlaczego to działa pokazując objectdumpa z plików main.o oraz foo.o ... no to zajrzyjmy po naszemu:
co widzimy w foo.o - no widzimy, że kompilator WYRAŹNIE zarezerwował sobie adres w pamięci RAM na dwa bajty, w której będzie przechowywana zmienna o nazwie dwa. I to jest OBIEKT ale widać, że ładnie zaadresowany w obszarze: .data.dwa
co natomiast widzimy w main.o ? No tu widzimy również obiekt ale niestety ma on co ciekawe rozmiar = 1
natomiast u roske ma rozmiar 4 -
kto zgadnie dlaczego ? Poza tym obiekt opisany jako COM, jest jak słusznie wyżej zauważył wyżej kolega
Marhef,
unallocated C external variables.
hmmm no jak to? myśli sobie kolega roske ? zresztą tak naprawdę to nie wiem co on myśli i co miały pokazać jego przykłady ... ale spróbujmy rozważyć dlaczego na wyświetlaczu LED
koledze roske niestety nie chciało się...
roske napisał(a):
(oczywiście, aby się nie motać z żelastwem, kompilacje i uruchamianie robimy na PC)
a szkoda, bo jakbyś sobie zadał minimu trudu i zauważył chociażby tę różnicę w rozmiarach: 4-bajty dla zmiennej dwa na PC, 2-bajty dla zmiennej dwa na AVR8 - no i ten tajemniczy rozmiar = 1 dla obiektu COM .... to już mogłoby cię to na coś naprowadzić. Tymczasem z jakąś przedziwną radością piszesz takie bzdurki:
roske napisał(a):
Przykład nie powinien się nawet dać skompilować, nieprawdaż?
roske ależ powinien się skompilować - tylko ty nie wiesz dlaczego tak się stało w tym przypadku a zaraz tobie pokażę przypadki kiedy się nie skompiluje i będziesz MOCNOOOO zdziwiony ...
otóż program się kompiluje TYLKO dlatego, że uznaje, że ktoś zdefiniował dwie zmienne przy czym (Uwaga! roske) nie zainicjalizował zmiennej "dwa" w pliku main.c ! W związku z tym nazwa ta otrzymała specyfikator COM - uznana została za zewnętrzną zmienną globalną ale tylko dzięki temu że nastąpiło przysłonięcie nazw z dwóch różnych klas.
no to teraz DRUGI WARIANT - roske popatrz - komentujemy linię w main.c
// dwa = 200;
OOO maaaj gaaad - i co my widzimy
? Ale ja nie będę zadawał zagadek jak roske, ponieważ wyciągnąłem żelaztwo - bo lubię to proszę na LCD tym razem CUD się stał - dżizas! zamiast liczby 200 wyświetliła się nam liczba
2pewnie roske teraz się cieszy bo to wg niego dowód na jego pomysł globalności ... Oczywiście jak zajrzymy do object dumpa to zobaczymy DOKŁADNIE to samo co wyżej !!! A więcnadal zadziała przysłanianie nazw ale TYLKO dlatego, że zmienna "dwa" zdefiniowana w main.c nie została zainicjalizowana!
W takim razie spróbujmy ją zainicjalizować jakąś wartością np 17
a kto nam zabroni? - proszę bardzo:
uuuuuuu .... buuuu - ooo jej - no i kompilator w końcu zwymiotował ... a ja się mu wcale nie dziwię. Też bym to zrobił, gdyby ktoś próbował mnie faszerować takim kodem ...
czyli co widzimy w czarnej ramce ?
Cytuj:
./main.o:(.data.dwa+0x0): multiple definition of `dwa'
roske - jak to? dlaczego ? No i w łeb wzięła teoria o tego typu globalności ....
No to teraz popatrz roske na ostatni obrazek, ponieważ jak się domyślam zaraz znowu wymyślisz jakieś teksty o fałszywości itp, tymczasem przekonaj się sam
dodałem nad funkcją main() nową funkcję o nazwie fun1, i wywołałem ją przed nadaniem nowej wartości = 300 zmiennej dwa. Tyle że podczas kompilacji kompilator najpierw MUSI ustalić miejsce w RAM dla zmiennej dwa i gdzie została przydzielona pamięć ? oczywiście w foo.c ponieważ w objecdupie foo.o widzimy tę rezerwację. Natomiast znowu - kompiluje się to ponieważ zmienna "dwa" z main.c jest tylko wydmuszką !
Teraz jeszcze raz sobie spróbuj zainicjalizować zmienną "dwa" w main.c i zobaczysz znowu figę z makiem od kompilatora:
widzisz Pan? ... i to co pokazałem strzałką i podkreślone - kompilator nie na darmo krzyczy że wcześniej taka zmienna została zdefiniowana w foo.c ! a że próbowałeś zainicjalizować JEDNĄ i DRUGĄ na etapie gdy kompilator będzie musiał umieścić to w BSS to dostaje ŚWIRA - bo nie wie - którą wartością, nie może tu już dojść do przysłonięcia nazw - ponieważ jawnie próbujesz inicjalizować dwa obiekty o TAKIEJ SAMEJ NAZWIE
Więc BZDURĄ jest twoja i kiśla teoria o pseudo waszej wymyślonej globalności ....
--------------------------------------------------------------------------------------------------------------
Tymczasem gdybyście DOKŁADNIEJ poczytali klasykę na temat ANSI C jak w wydaniu :
The C Programming Language - Kernighan and Ritchie
albo chociaż Praty to byście w końcu zrozumieli co to jest DEFINICJA zmiennej i jej DEKLARACJA i czym się różnią ! Wtedy byście nie pietruszkowali tego co do tej pory tylko napisalibyście ten kod jak się należy czyli - DEFINICJA zmiennej np w foo.c, do tego jej DEKLARACJA w foo.h (dokładnie tak samo jak ze zmienną "jeden" w twoim przykładzie i WSZYSTKO by pięknie działało !) .... zamiast się upierać jak piszesz z uporem maniaka przy wydumanych teoriach albo jak kisiel pisać , że ja rzekomo ogłaszam jakieś swoje zasady ! Bzdura - ja się tylko uczę i to co doczytam u klasyków albo stwórców C to wtedy się tym dzielę. Oczywiście mogę się mylić, mogę popełniać błędy - być może nawet w tych wyjaśnieniach coś mało precyzyjnie opisałem ... ale myślę, że teraz są jasne i przejrzyste.
Już nie wspomnę , że pisałem tobie roske abyś dla przykładu założył kolejny plik np foo2.c w którym powołasz kolejny raz definicję zmiennej o nazwie "dwa" - to sam wiesz, że już taka głupota się nie uda od razu z marszu - bo kompilator wywali błąd ... ale ty rozbrajająco napisałeś - no i co z tego, że wywali ?
Na koniec - zamiast zadętych tekstów o fałszywości, o biciu piany i tym podobnych - ochłoń, przeczytaj na spokojnie - a jak będziesz miał jeszcze jakieś uwagi albo nie będziesz się zgadzał z tym co ja pokazałem to napisz - chętnie podyskutuję dalej - ale pod warunkiem, że zaczniesz dyskutować kulturalnie i już na luzie ok ?