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.