Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Konveryija nekonstantnog tipa u konstantan

[es] :: C/C++ programiranje :: Konveryija nekonstantnog tipa u konstantan

[ Pregleda: 3399 | Odgovora: 9 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

Nedeljko
Nedeljko Stefanović

Član broj: 314
Poruke: 8632
*.dial.InfoSky.Net.



+2790 Profil

icon Konveryija nekonstantnog tipa u konstantan03.03.2005. u 20:35 - pre 233 meseci
Zašto ne može da se konvertuje klasa list<T*> u klasu list<const T*>, gde je T neka klasa?
Nije bitno koji su zaključci izvučeni, već kako se do njih došlo.
 
Odgovor na temu

filmil
Filip Miletić
Oce Technologies B.V., inženjer
hardvera
Arcen, NL

Član broj: 243
Poruke: 2114
*.ipact.nl.

Jabber: filmil@jabber.org
ICQ: 36601391


+3 Profil

icon Re: Konveryija nekonstantnog tipa u konstantan03.03.2005. u 22:27 - pre 233 meseci
Citat:
Zašto ne može da se konvertuje klasa listT* u klasu listconst T*, gde je T neka klasa?
To bi tražilo da se prođe kroz celu listu i da se uradi odgovarajuća konverzija. Kako kompajler pojma nema šta da uradi da bi to postigao, konverzija nije moguća.

Pošto mi znamo da se iza klase list krije STL za listu, znamo da bi konverzija mogla da se odradi na primer kada bismo napravili iterator, prošli kroz sve elemente i recimo napravili listu konstantnih pointera. Kompajler to ne zna.

Nadam se da je sad jasnije.

f
 
Odgovor na temu

Nedeljko
Nedeljko Stefanović

Član broj: 314
Poruke: 8632
*.dial.InfoSky.Net.



+2790 Profil

icon Re: Konveryija nekonstantnog tipa u konstantan04.03.2005. u 00:24 - pre 233 meseci
Ovako, da navedem primer i da vidimo šta nije logično u mom shvatanju jezika.
Code:

i#include <list>

int main()
{
    list <int*> a;
    list <const int*> b;

    b = a;   // greska

    return 0;
}

Kada bih ja pravio C++ kompajler, je bih jednostavno iskopirao listu a, pri čemu bi b postala upravo ta kopija i pritom bih zabranio opercije koje menjaju sadržaj na koji pokazuje iterator tipa list<const int*>::iterator, i pri čemu bi jedino takav iterator mogao da se koristi nad listom b. Drugim rečima, sve metode objekta b koje kao rezultat vraćaju iterator bi vraćale rezultat tipa list<const int*>::iterator (sa eventualnim const ispred) koji se ne može konvertovati u tip list<int*>::iterator (obrnuta konverzija bi bila moguća). Ne razumem zašto C++ standard nije baš takav i zašto se C++ kompakjleri tako ne prave.
Nije bitno koji su zaključci izvučeni, već kako se do njih došlo.
 
Odgovor na temu

Dragi Tata
Malo ispod Kanade

Član broj: 1958
Poruke: 3906
*.bos.east.verizon.net.



+6 Profil

icon Re: Konveryija nekonstantnog tipa u konstantan04.03.2005. u 03:11 - pre 233 meseci
Idi na comp.std.c++ pa pitaj.
 
Odgovor na temu

filmil
Filip Miletić
Oce Technologies B.V., inženjer
hardvera
Arcen, NL

Član broj: 243
Poruke: 2114
*.et.tudelft.nl.

Jabber: filmil@jabber.org
ICQ: 36601391


+3 Profil

icon Re: Konveryija nekonstantnog tipa u konstantan04.03.2005. u 09:07 - pre 233 meseci
Citat:
Kada bih ja pravio C++ kompajler, je bih jednostavno iskopirao listu...Ne razumem zašto C++ standard nije baš takav i zašto se C++ kompakjleri tako ne prave.
Previše očekuješ od jadnog kompajlera.

Kompajler pojma nema šta je to šablon list. list ni u kom slučaju nije povezan sa C++ kompajlerom; to je eksterna biblioteka.

On samo zna da ako deklarišeš šablon list, da treba da prođe kroz tabelu simbola i ugradi kod tog-i-tog metoda iz simbola sa datim imenom. Dakle zamena je na čisto sintaktičkom nivou: supstitucija.

Ti tražiš od kompajlera da prepozna semantiku, odnosno da nekako „zna“ da šablon list baš predstavlja listu, a ne recimo bitmapu, i da zna da metod ::begin() vraća iterator koji pokazuje na početak liste itd.

Jedini danas poznati način da se ovako nešto uradi jeste da se ode u knjižaru, kupi knjiga o STL-u, pročita i razume šta u njoj piše. Ako budeš napravio C++ kompajler koji ovo ume da uradi, osigurao si sebi mesto u istoriji uz Tjuringa, Knuta, i ostale. :)

Druga je priča kada su liste i kontejneri ugrađeni tipovi u neki jezik. C++ međutim ne radi tako. Jedini način da dobiješ to što želiš je da sam obezbediš semantiku.

Kod dodele, specijalizuj operator= za tipove koji te zanimaju i u okviru definicije metoda objasni računaru šta želiš da uradiš. To bi trebalo da bude dovoljno.

A zašto ovo nije definisano unapred? Verovatno zato konverzija u ovom slučaju nije jednoznačno definisana.

Neko će negde želeti da je uradi na drugačiji način, recimo da pre konverzije svim intovima promeni predznak. Jeste, to je krajnje neuobičajeno, ali da li bi mogao da se opkladiš da nikome to nikada neće pasti na pamet ili trebati? Ili realniji primer: da li bi mogao da se opkladiš da se neće pojaviti dva programera, koji oba žele da koriste operator dodele, pri čemu jedan hoće deep kopiju, a jedan shallow kopiju kao rezultat?

Varijacija na temu je suviše da bi šabloni obezbeđivali sve njih ponaosob. STL zato daje šablone, dakle šemu za generisanje različitih kombinacija kontejnera i algoritama. IMHO je od C++ standarda sasvim dovoljno što imaš mogućnost da dopišeš specijalizaciju operatora dodele onako kako ti odgovara za datu primenu; ali ćeš morati da je napišeš sam.

f
 
Odgovor na temu

Nedeljko
Nedeljko Stefanović

Član broj: 314
Poruke: 8632
*.dial.InfoSky.Net.



+2790 Profil

icon Re: Konveryija nekonstantnog tipa u konstantan04.03.2005. u 10:49 - pre 233 meseci
Filmil, hvala na trudu oko mene, smatram da sam odgovor razumeo, ali i dalje nisam bio zadovoljan, pa sam pronašao odgovor koji se zapravo uklapa u ono što si pisao. Znam ja koja je razlika između tipova ugrađenih u jezik (tj. osnovnih tipova) i tipova koji se preko njih definišu (složenih tipova), ali takođe sam smatrao da pošto konverzija iz tipa int* u tip const int* postoji, da bi sam mehanizam jezika trebao da obezbedi i konverziju tipova (recimo korisnički definisanih) koji sadrže polja tih tipova, osim ako u toj klasi ne postoji neka "zvrčka" zbog koje tu konverziju nije moguće definisati automatski.

Recimo, imam dve klase A i B koje se razlikuju samo po tipovima polja, rezultta metoda i njihovih argumenata tako da

1. Tip polja klase B ima definisanu konverziju u tip odgovarajućeg polja klase A.
2. Tip rezultata metoda klase B ima definisanu konverziju u tip rezultata odgovarajuće metode klase B.
3. Tipovi argumenata metode klase A imaju definisane konverzije u tipove argumenata odgovarajuće metode klase B uzimajući ih u istom redosledu.

Zašto da onda ne bude automatski definisana konverzija iz klase B u klasu A? Ovde je problem izgleda u tome što klasa list<T> IMA metode koje prihvataju argument čiji tip sadrži T (recimo konstruktor kopije ima argument tipa list<T>&), pa pošto obrnuta konverzija nije moguća, onda nije ni moguća smislena automatska konverzija između takvih klasa. U svakom slučaju, C++ ne vrši ni automatsku konverziju pod gore navedenim uslovima, već zahteva eksplicitno definisanu konverziju.
Nije bitno koji su zaključci izvučeni, već kako se do njih došlo.
 
Odgovor na temu

filmil
Filip Miletić
Oce Technologies B.V., inženjer
hardvera
Arcen, NL

Član broj: 243
Poruke: 2114
*.et.tudelft.nl.

Jabber: filmil@jabber.org
ICQ: 36601391


+3 Profil

icon Re: Konveryija nekonstantnog tipa u konstantan04.03.2005. u 12:00 - pre 233 meseci
Citat:
osim ako u toj klasi ne postoji neka "zvrčka" zbog koje tu konverziju nije moguće definisati automatski.
Utvrđivanje da li „zvrčka“ postoji ili ne je glavni problem. „Zvrčka“ je problem semantičke prirode, a C  odn. C++ kompajleri se bave samo i isključivo sintaksom.

Da bi se uradilo ono što želiš, potrebno je naterati kompajler da nekako razume značenje listi. Kako je značenje listi pitanje konvencije, dakle dogovora, kompajler bi morao nekako da razume taj dogovor.

Pritom ne mislim da se pretrese STL i mehanizam za „ispunjavanje želja“ ugradi u neku novu verziju g++-a na primer. To bi rešilo tvoj pojedinačni problem, ali ne i sve ostale moguće probleme istog tipa. Morao bi da napraviš sistem koji bi razumevao i sve buduće konvencije. Da li je lakše da napraviš takav mehanizam (ili da li je uopšte moguće) ili da u svom programu samo dopišeš funkciju operator= koja radi što ti treba?

f
 
Odgovor na temu

Nedeljko
Nedeljko Stefanović

Član broj: 314
Poruke: 8632
*.dial.InfoSky.Net.



+2790 Profil

icon Re: Konveryija nekonstantnog tipa u konstantan04.03.2005. u 18:06 - pre 233 meseci
Pozdrav Filmil.

Taman sam pomislio da sam dao objašnjenje zašto kompajler ne može da izađe na kraj sa mojim problemom, već ja treba ručno da ga rešavam, i da možemo da zaključimo ovu temu, a ono ispade da je došlo do nesporazuma. Mislim da nisi razumeo moj prethodni post, pa bih da pojasnim stvari.

Kompajler je program koji na ulazu prihvata sors (kao nekakav niz znakova lišen svakog smisla), a na izlazu proizvodi izvršni program (koji je za njega takođe samo niz bajtova i ništa više). Pošto je kompajler program, on od ulaza mora da proizvodi izlaz po nekim formalnim pravilima. Drugim rečima, ta transformacija mora da bude algoritamski opisiva, jer program i može da radi samo po algoritmu. Zato kompajler, kao i bilo koji drugi program ne može da "razume" značenje tog ulaza, već na njega samo primenjuje formalna pravila. Sintaksa je upravo ono što je obuhvatljivo formalnim pravilima.

Neke "zvrčke" su sintaksno uhvatljive. Uvek se mogu formulisati dovoljni (ali ne i potrebni) pod kojima neki tip "zvrčke" ne može da postoji. To jest, neke situacije su sintaksno uhvatljive. Na primer, ne postoji kompajler koji može da utvrdi u kojoj liniji programa koje promenljive sigurno moraju imati dodeljene vrednosti. Slučajno sam položio ispit iz teorije rekurzija, pa znam da taj problem nije algoritamski rešiv, pa se i ne može napisati takav kompajler.

Ali C# kompajler može da proveri da li su zadovoljena pravila sigurne dodele za neku promenljivu u nekoj liniji. To je sintaksan skup pravila koji predstavlja DOVOLJAN, ALI NE I POTREBAN sistem uslova da neka promenljiva u nekoj liniji MORA imati dodeljenu vrednost. Na primer, u sledećem kodu je sve u redu.
Code:

int abs(int x)
{
    int rez;

    if (x<0)
        rez = -x;
    else
        rez = x;

    return rez;
}

Sa druge strane, sledeći kod iako semantički ispravan, ne zadovoljava ta pravila. On je sintaksno neispravan u jeziku C#.
Code:

bool jednaki(int a, int b)
{
    bool rez;

    if (abs(a-b)>0)
        rez = false;

    if (a==b)
        rez = true;

    return rez;
}

Dakle, C# kompajler ne zna semantiku, ali zna za pravlo sigurne dodele koje pnavljam, predstavlja dovoljan, ali ne i potreban sistem uslova da neka promenljiva u nekoj liniji uvek ima dodeljenu vrednost. Ja sam prethodni put naveo sistem dovoljnih uslova da AUTOMATSKA smislena konverzija (dakle, bez ulaženja u semantiku) između klasa bude moguća. To što kompajler ne radi po tim (sintaksnim) pravilima, ne znači da ga nije moguće napraviti.

U mom slučaju je problem u sledećem. Klasa list<T> ima metode koje prihvataju bar jedan argument tipa T (po vrednosti ili adresi, svejedno). Recimo, takav je konstruktor kopije ili operator dodele. Iz tog razloga bi za smislenu automatsku konverziju tipa list<A> u tip list<B> bilo neophodno da postoji automatska konverzija iz tipa A u tip B. Ali automatska konverzija tipa const int* u tip int* nije moguća, i zbog toga nije moguće napraviti ni C** kompaler koji bi "progutao" konverziju između ovih šablonskih tipova.

Pročitaj sistem pravila za klase koji sam predložio, videćeš da su u ovom slučaju potrebne konverzije u oba smera, a konverzija između tipova const int* i int* je definisana samo i jednom.
Nije bitno koji su zaključci izvučeni, već kako se do njih došlo.
 
Odgovor na temu

Nedeljko
Nedeljko Stefanović

Član broj: 314
Poruke: 8632
*.dial.InfoSky.Net.



+2790 Profil

icon Re: Konveryija nekonstantnog tipa u konstantan04.03.2005. u 19:20 - pre 233 meseci
U stvari, sistem uslova koji sam predložio nije dobar. Bilo bi neophodno imati pretpostavke o tome koje operacije nad poljima vrše nestatičke metode i da li te operacije postoje u slučaju klase u koju se data klasa konvertuje. No, to ne bi bilo moguće bez ulaženja u definiciju metoda, pa u zaglavljima ne bi moglo da se utvrdi da li je konverzija moguća ili ne. Zato takva mogućnost i nije predviđena.
Nije bitno koji su zaključci izvučeni, već kako se do njih došlo.
 
Odgovor na temu

filmil
Filip Miletić
Oce Technologies B.V., inženjer
hardvera
Arcen, NL

Član broj: 243
Poruke: 2114
*.ipact.nl.

Jabber: filmil@jabber.org
ICQ: 36601391


+3 Profil

icon Re: Konveryija nekonstantnog tipa u konstantan05.03.2005. u 00:14 - pre 232 meseci
Citat:
 No, to ne bi bilo moguće bez ulaženja u definiciju metoda,
Upravo je u tome stvar. Kod C odn. C++ kompajlera ograničenja su veća: sve što nije moguće sasvim pravolinijski prevesti u mašinski kod, nije dopušteno. Granica postavljena manje-više empirijski, ali kako god bilo, sam kompajler se ne udubljuje preterano u kod.

Za takve stvari postoje naknadni alati koji ubacuju malo više „pameti“ i konteksta u analizu programskog koda, odn. runtime slike programa, kao što su lint ili valgrind.

f
 
Odgovor na temu

[es] :: C/C++ programiranje :: Konveryija nekonstantnog tipa u konstantan

[ Pregleda: 3399 | Odgovora: 9 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.