Citat:
icobh: Mene zanima jedna stvar. Zašto mogu da ovaj kôd kojeg sam ja lično pisao, da kompajliram kod sebe, kolege, na faxu i to sa bcc-om, msvc-om ali ne i sa gcc-om? Zašto to? Zašto to sad jedno const igra toliku ulogu?
Pretpostavljam zato što standard (ANSI, ISO, šta li) negde kaže da je prototip kopirajućeg konstruktora je
T (const T &) i nikoji drugi. GCC ti onda u poruci greške praktično kaže da tvoja klasa nema ispravan kopirajući konstruktor. Dakle, GCC se podrazumevano (bez posebnih opcija) ponaša po standardu — što je dobro — dok ti na faksu i kod kolege ne — što je loše. Kao što Nemanja već reče.
E sad, i standarde pišu ljudi, pa je uvek bitno uočiti
zašto je dobro tako kako je standard propisao. Kopirajući se poziva u mnogim situacijama nad objektom koji je privremeno konstruisan u lancu naredbi. Tada, ako bi mu bilo dozvoljeno da prima nekonstantni upućivač, prvo bi mogao da izmeni taj privremeni objekat (znači mogući gubitak podataka), i drugo ne bi mogao više da funkcioniše kada se u lancu pojavi konstantan objekat. Zato nema smisla da kopirajući prima nekonstantni upućivač.
Na strani izvedbe, GCC bi (kao i ti drugi) po uobičajenom mehanizmu poklapanja poziva i prototipa mogao komotno da pozove onaj sa nekonstantnim upućivačem. Dalje, ako ispratiš redosled poziva pri izvršavanju, videćeš da GCC nigde nije ni pozvao kopirajući; npr.
Skup tmp3(c.unija(a.unija(b))), uz drugačije definicije ovih funkcija, moglo je biti i brzinski optimalnije
Skup tmp3; unija(a, unija(b, unija(c, tmp3))), što je GCC primetio i sam transformisao u izlaznom kôdu. Drugim rečima, GCC je em mogao da pozove prvobitni kopirajući, em mu kopirajući čak nije ni trebao, pa ti je opet prijavio grešku. To znači da su se programeri koji rade na GCCu morali potruditi da dodaju ovo kao posebnu mogućnost, a koja se tebi čini kao njegova loša osobina :)
Kad već pomenuh gore automatsku optimizaciju, probaj sa tim BCCom i MSVCom da prisiliš poziv kopirajućeg. Npr. staviš
Skup tmp1b(tmp1);, i daj kopirajućem da nešto ispiše, da budeš siguran da je pozvan. Da li tada kôd i dalje prolazi? (Moguće je da su se zeznuli pri optimizaciji, da ne proveravaju prototip kopirajućeg kada primete da nije ni potreban.)