[QGHG-it-dev-list] Opšta pitanja

Marko Vojinovic vmarko at ipb.ac.rs
Wed Mar 9 00:33:20 CET 2022


Pozdrav Dusane,

Nisam do kraja siguran sta te tacno zbunjuje, i verovatno ce Nenad i Jaroslav moci da ti odgovore pametnije od mene, ali evo da probam...

Prvo --- obrati paznju da na pocetku *svakog* .cpp fajla (a ne samo main.cpp fajla!!) include-ujemo ceo triangulator.hpp fajl, koji u sebe include-uje sve ostale .hpp fajlove. To znaci da preprocesor dobije deklaracije *svih* klasa i *svih* f-ja kroz triangulator.hpp (sve je forward-deklarisano u .hpp fajlovima), pre nego sto stigne do bilo kog parceta koda koje zapravo treba kompajlirati. Tako da (nakon preprocesora) kompajler tj. prevodilac ima sve simbole i sva imena vec definisana kad pocne da radi na bilo kom .cpp fajlu. Tako da nema za sta da prijavi gresku, ni za jedan od .cpp fajlova koji kompajlira.

Drugo --- treba da ti bude jasan dizajn naseg koda. Mi pravimo nesto sto se zove "static library", biblioteka rutina koju korisnik treba da linkuje sa svojim main.cpp fajlom u nekom svom kodu, i da poziva gotove f-je koje smo mi napravili. Nas main.cpp radi upravo tako, i sluzi nam za testiranje f-ja biblioteke. Sam main.cpp naravno nije deo biblioteke, ali svi ostali .hpp i .cpp fajlovi jesu.

Biblioteke rutina su potpuno normalna i standardna stvar, i vec ih koristis u svakodnevnom programiranju --- na primer, kada treba nesto da izracunas pomocu trigonometrijskih f-ja ili sl. u svom C++ kodu, ti include-ujes math.h header (ili kako se vec zove) u svoj main.cpp. I onda, nakon kompajliranja tvog fajla, linker automatski ulinkuje u tvoj izvrsni fajl i biblioteku math-library.a (verovatno se zove drugacije, i nije staticka nego neki .dll ili stagod), u kojoj se nalaze prekompajlirani object-fajlovi koji sadrze implementacije za sinus, kosinus, isl --- tebi je dovoljno samo da ih pozoves u svom main.cpp kodu, jer ih je neko drugi vec implementirao i spakovao u biblioteku. Neki zamisljeni krajnji korisnik dakle treba da upotrebljava nasu biblioteku rutina na *potpuno isti* nacin kao sto upotrebljava math.h, string.h, stagod.h...

Detalji i objasnjenja sta su biblioteke rutina (static, shared i dynamic tipovi), kako rade i cemu sluze, mozes da procitas u Program Library HOWTO [1], ako te zanima. HOWTO je pisan za Linux, ali sustina i koncepti su isti i za Windows (mozda se samo drugacije zovu, .dll ili vec kako). U svakom slucaju, rezime je da je staticka biblioteka prosto jedna arhiva (poput .zip fajla) u koju je "zapakovana" gomila kompajliranih object-fajlova u jednu konzistentnu celinu. I onda, kada korisnik pise svoj main.cpp fajl, on prosto moze da include-uje triangulator.hpp (cime za preprocesor i kompajler obezbedi forward-deklaracije svih imena i simbola), zatim kompajlira svoj main.cpp (koji koristi te f-je i simbole), i na kraju u njega ulinkuje nasu biblioteku (triangulator-library.a), cime dobije izvrsni (executable) fajl. I to je sve.

Nas main.cpp fajl to vec sada tako radi (mozes da pogledas build-script.sh da vidis kako g++ pravi biblioteku i kako je ulinkuje sa main.cpp-om...), ali prvi "ozbiljan" primer upotrebe nase biblioteke ce da bude GUI (koji je Jaroslav poceo da pravi) --- to ce na kraju da bude jedan izvrsni fajl, koji ce da otvara prozore po ekranu i da pise i crta po njima, i usput ce da poziva i izvrsava f-je iz nase biblioteke rutina. Jaroslav ce u main.cpp za GUI da include-uje triangulator.hpp, da poziva po potrebi sve f-je iz nase biblioteke (kako mu koja gde treba), i onda ce tokom kompajliranja GUI koda da ulinkuje triangulator-library.a biblioteku (koja je po pretpostavci vec ranije napravljena), cime ce dobiti izvrsni fajl "triangulator-gui.exe". Naravno, moguce je i potrpati zajedno sav kod (i za biblioteku i za GUI) na jedno mesto i kompajlirati sve odjednom. Ali inteligentnije je da imamo dizajn tako da biblioteka rutina bude konceptualno odvojena od GUI-ja. Tako bismo omogucili nekom tre
 cem korisniku da upotrebljava nase f-je u nekom svom izvrsnom programu, a ne iskljucivo kroz nas GUI ili sl.

I na kraju --- ne znam kako Visual Studio tretira ceo kod, sta sa cime linkuje itd., ali mozes u build-script.sh da vidis kako to radi g++, i sta je cilj. Pretpostavljam da VS moze da se podesi da sve nase .cpp fajlove spakuje u jednu biblioteku triangulator-library.dll, koju ce onda moci da ulinkuje prilikom kompajliranja main.cpp fajla i da dobije .exe fajl. VS verovatno nesto slicno radi vec i sada, samo mozda ne pravi taj .dll fajl nego odmah sve object-fajlove (od svakog naseg pojedinacnog .cpp fajla) na kraju zajedno ulinkuje sa main.cpp u izvrsni fajl. Za sada jos uvek nije vazno kako on to tacno izvodi --- kreiranje .dll fajla cemo da rascistimo i organizujemo sve kako treba kad budemo napravili Makefile za ceo projekt, zasad jos mozemo bez toga.

Ok, nadam se da cela ova prica baca malo vise svetla na zamisao i organizaciju celog koda. ;-)

:-)
Marko

[1] https://tldp.org/HOWTO/Program-Library-HOWTO/index.html


Dr. Marko Vojinovic
Group for Gravitation, Particles and Fields
Institute of Physics
University of Belgrade
======================
home page: www.markovojinovic.com
e-mail:    vmarko at ipb.ac.rs



On Tue, 8 Mar 2022, Dusan Cvijetic wrote:

> Pozdrav,
> 
> Otvaram ovaj thread jer mi se čini da bi bilo dobro da imamo sva pitanja koja nisu vezana za neki konkretan zadatak na jednom mestu.
> 
> Ako se sećate, u početku sam imao problem što kod nije mogao da se prevodi u Visual Studio-u, dok je sasvim dobro radio sa gcc. To je u međuvremenu razrešeno, ali sada mi uopšte nije
> jasno kako se kod za triangulator bilo gde prevodi.
> 
> Koliko mi je poznato, prevođenje se vrši iz tri faze: pretprocesor vrši leksičku obradu, zatim se izdvajaju tokeni iz sirovog teksta, koje builder koristi da bi kreirao .obj fajlove. Na
> kraju, linker prolazi kroz .obj fajlove i povezuje deklaracije sa definicjama, ukoliko se nisu nalazile u istom fajlu.
> 
> Stil programiranja sa kojim sam se do sad susreo je nalagao da u .hpp fajl u kome koristim neko ime uključim .hpp fajl sa odgovarajućom deklaracijom. Tako bih, recimo, morao da uključim
> colors.hpp direktno u classes.hpp, jer je jedno od polja KSimplex-a lista boja koje ga opisuju. Kada uključim colors.hpp na početku fajla, builder zna deklaraciju klase Color i nema
> problema.
> 
> Međutim, mi to ne radimo, već sve deklaracije uključujemo u triangulator.hpp, i zatim to dalje u main.cpp. Nije mi jasno kako builder "zna" deklaraciju klase Color unutar fajla
> classes.hpp.
> 
> U knjizi (Milićev, 1995, str. 71) sam našao:
>
>       Zbog potpuno nezavisnog prevođenja jednog fajla (prevodilac "ne vidi" ništa drugo osim onoga što se nalazi u fajlu koji trenutno prevodi), svaki programski fajl treba da
>       sadrži sve što je potrebno za uspešno prevođenje tog fajla. To znači da je potrebno da u svakom fajlu postoje odgovarajuće deklaracije svih imena koja se u fajlu koriste.
>       Svako korišćenje imena bez prethodne deklaracije u fajlu prevodilac prijavljuje kao grešku. /.../ Deklaracije imena navode se u svim fajlovima u kojima se ta imena koriste.
> 
> 
> Prema gornjem teksu, očekivao bih da prevodilac baci grešku jer mu ime klase Color nije definisano. Ipak, nešto ranije na istoj strani, prof. Milićev je napisao i:
>
>       Prevodilac prevodi svaki programski fajl (skoro) potpuno nezavisno, ne znajući koji sve fajlovi čine program.
> 
> 
> Pretpostavio sam da rešenje moje nejasnoće leži u ovome (skoro), ali nisam uspeo na internetu da nađem nikakve detalje koji bi mi razjasnili kako radi prevodilac u VS.
> 
> Da li bi neko mogao da mi objasni zašto naš kod radi?
> 
> Pozdravi,
> Dušan
> 
> (1) Milićev, D, Objektno orijentisano programiranje na jeziku C++, Beograd, 1995.
> 
> 
> 
>


More information about the QGHG-it-dev-list mailing list