Hozzászólások
[quote:99b4888a0f="meditor"]A staticnak valóban más a jelentése a globális
és a lokális változóknál. A lokális változó esetében a változó
nem lapozódik ki a memóriából, globális változó esetén pedig
a változó exportálási lehetőségét zárja ki. Ugyanakkor EGY modulon
belül nyugodtan lehet használni az extern static valami formulát,
hibát nem jelez, az persze más kérdés, hogy tök értelmetlen.
A static c++ - ban újabb jelentéssel bűvül, de ez már egy másik topik lenne. (-::
Ne haragudj, de ez marhaság. Semmi köze a static-nak a lapozáshoz. Idézem az alapművet (K&R: A C prog. nyelv):
"a belső static változók ... állandóan fennmaradnak, és nem jönnek létre, ill. szűnnek meg a fv. minden egyes aktivizálása alkalmával. Eszerint a belső static változók a fv-en belül saját, állandó tárat képeznek. ... A külső static változók annak a forrásállománynak a további részében lesz ismert, amelyben deklarálták, de érvényességi tartománya nem terjed ki egyetlen másik álloményra sem." Amúgy a fordítónak az a baja, hogy az extern és a static két különböző tárolási osztályt határoz meg. Az egyik (extern) szerint valahol máshol lesz megadva a tárolóterületfoglalás, a másik (sttic) szerint most itt azonnal megadjuk a területfoglalásra vonatkozó információt.
- A hozzászóláshoz be kell jelentkezni
[quote:8b891eccc4="meditor"]A lokális változó esetében a változó
nem lapozódik ki a memóriából
Tessék?
KisKresz
- A hozzászóláshoz be kell jelentkezni
Valaki kiszámolta fejben, hogy minek kéne kijönnie?
Mert szerintem a t1 tömb 0. eleméhez hozzá sem nyúl a program
tehát csak azok a megoldások jók, ahol ezen a helyen a kiinduló
érték (1) szerepel. (Azt saccolom, hogy az 1678 a jó t1-re.)
Az optimalizáló opciók hatással lehetnek a kifejezések
kiértékeliési sorrendjére. A feladat kiváló példa arra,
hogy hogyan NEM szabad ciklust szervezni.
Egyébként szerintem nem igaz, hogy az i értéke definiálatlan,
mert a for ciklus fejében kezdőértéket kap. Én SOHA nem használok
egyébként for ciklust (csak és kizárólag while-t használok) és ciklus előtt
mindig inícializálom az értékeket.
- A hozzászóláshoz be kell jelentkezni
Még valami, ami a volatile-lal kapcsolatos. Szerintem itt nem indokolt.
A fordító ugyanis mindent tudhat(na) a változóról, ha valamit mégsem,
az a programozó hibája. A volatile én akkor használom, ha egy változó
értékét az általam írt programon kívül más is meghatározhatja. Ilyen
lehet például egy hardverállapot, egy idő, azaz többnyire olyan
dolgok, amik megszakításból kezelődnek le. Ha nagyon szigorú
kódot írunk unix alatt (ahol minden file, még a hardver is) nem nagyon
van szükség volatile-ra. Ebben az esetben egyáltalán nem indokolt ...
szerintem (-::
Ha felmerül a gyanú, hogy a változót a rendszer ki-be pakolja, akkor
static-ként kell definiálni, nem volatile-ként.
- A hozzászóláshoz be kell jelentkezni
[quote:1b2a4ef93d="KisKresz"][quote:1b2a4ef93d="meditor"]A lokális változó esetében a változó
nem lapozódik ki a memóriából
Tessék?
KisKresz
Más szavakkal: a változó értéke két függvényhívás közt is megmarad.
Ha nem static, akkor minden fvhívásnál újból és újból lefoglalódik
a lokális változó, újra kell inícializálni, és a végén a változó helye
felszabadul.
- A hozzászóláshoz be kell jelentkezni
Slack 10.0 alatt simán szól -Wall-ra, hogy az i-vel gondok lesznek.
A feladat megoldása az tehát, hogy program kimenete nem
definiálható.
- A hozzászóláshoz be kell jelentkezni
Ha a programot átalakítom így:
for( i=0;i<4; ) {t3[i]=t1[i];i++; t1[i]=t2[i];i--; t2[i]=t3[i];i++;}
mely kód ELMÉLETILEG equivalens az eredetivel (postinkremens index),
simán lefut, hibajelzés nélkül és ezt az eredmény adja (amit jósoltam
korábban):
1678
1678
1678
Szerintem a tanárúr erre gondolt. A vizsgákon nekem mindig az okozta
a fejtörést, hogy a több lehetséges válasz közül, vajon melyikről gondolja
a tanár azt, hogy helyes. (-::
- A hozzászóláshoz be kell jelentkezni
[quote:7d2983c02f="meditor"][quote:7d2983c02f="KisKresz"][quote:7d2983c02f="meditor"]A lokális változó esetében a változó
nem lapozódik ki a memóriából
Tessék?
KisKresz
Más szavakkal: a változó értéke két függvényhívás közt is megmarad.
Ha nem static, akkor minden fvhívásnál újból és újból lefoglalódik
a lokális változó, újra kell inícializálni, és a végén a változó helye
felszabadul.
Azért valljuk be, ez azért nem ugyanaz :-) Mellesleg megnéztem a kezdeti barom kódot FreeBSD alatt, és gcc 3.4.4 és a legutolsó TenDRA fordító -tök_ ugyanazt a marhaságot állította elő. Az "int a=a" kód legalább más kimenetet generált e két fordítóval :-)
- A hozzászóláshoz be kell jelentkezni
Mostmar valaki nezze mar meg pls, akinek eredetileg az optimalizalt forditas hibas ertekeket adott vissza, hogy volatile-al is tenyleg hibasat ad e vissza, mert mar kivancsi lettem!
Mint fentebb irtam a volatile-nak CSAK azert kellene segiteni, mert akkor a fordito nem optimalizal a valtozoval. Mivel optimalizalas nelkul jol mukodott, ezert volatile-val is jol kellene (szvsz). Persze a volatile itt az ganyolas, de az eredeti kod is az.
- A hozzászóláshoz be kell jelentkezni
[quote:f63d250dbb="Zahy"][quote:f63d250dbb="meditor"][quote:f63d250dbb="KisKresz"][quote:f63d250dbb="meditor"]A lokális változó esetében a változó
nem lapozódik ki a memóriából
Tessék?
KisKresz
Más szavakkal: a változó értéke két függvényhívás közt is megmarad.
Ha nem static, akkor minden fvhívásnál újból és újból lefoglalódik
a lokális változó, újra kell inícializálni, és a végén a változó helye
felszabadul.
Azért valljuk be, ez azért nem ugyanaz :-) Mellesleg megnéztem a kezdeti barom kódot FreeBSD alatt, és gcc 3.4.4 és a legutolsó TenDRA fordító -tök_ ugyanazt a marhaságot állította elő. Az "int a=a" kód legalább más kimenetet generált e két fordítóval :-)
Na jó, nem ugyanaz (-:: , de én legalább nem tanítom!
- A hozzászóláshoz be kell jelentkezni
[quote:9dfa2790a2="LeslieT"]Mostmar valaki nezze mar meg pls, akinek eredetileg az optimalizalt forditas hibas ertekeket adott vissza, hogy volatile-al is tenyleg hibasat ad e vissza, mert mar kivancsi lettem!
Mint fentebb irtam a volatile-nak CSAK azert kellene segiteni, mert akkor a fordito nem optimalizal a valtozoval. Mivel optimalizalas nelkul jol mukodott, ezert volatile-val is jol kellene (szvsz). Persze a volatile itt az ganyolas, de az eredeti kod is az.
Megnéztem, a volatile nem használ neki.
- A hozzászóláshoz be kell jelentkezni
[quote:42b31e7dbd="meditor"][quote:42b31e7dbd="LeslieT"]Mostmar valaki nezze mar meg pls, akinek eredetileg az optimalizalt forditas hibas ertekeket adott vissza, hogy volatile-al is tenyleg hibasat ad e vissza, mert mar kivancsi lettem!
Mint fentebb irtam a volatile-nak CSAK azert kellene segiteni, mert akkor a fordito nem optimalizal a valtozoval. Mivel optimalizalas nelkul jol mukodott, ezert volatile-val is jol kellene (szvsz). Persze a volatile itt az ganyolas, de az eredeti kod is az.
Megnéztem, a volatile nem használ neki.
Ok, akkor meggyoztetek :wink:
- A hozzászóláshoz be kell jelentkezni
[quote:668906db86="meditor"][quote:668906db86="Zahy"][quote:668906db86="meditor"][quote:668906db86="KisKresz"][quote:668906db86="meditor"]A lokális változó esetében a változó
nem lapozódik ki a memóriából
Tessék?
KisKresz
Más szavakkal: a változó értéke két függvényhívás közt is megmarad.
Ha nem static, akkor minden fvhívásnál újból és újból lefoglalódik
a lokális változó, újra kell inícializálni, és a végén a változó helye
felszabadul.
Azért valljuk be, ez azért nem ugyanaz :-) Mellesleg megnéztem a kezdeti barom kódot FreeBSD alatt, és gcc 3.4.4 és a legutolsó TenDRA fordító -tök_ ugyanazt a marhaságot állította elő. Az "int a=a" kód legalább más kimenetet generált e két fordítóval :-)
Na jó, nem ugyanaz (-:: , de én legalább nem tanítom!
Nem, de hangoztatod.. Ami majdnem ugyanaz :D
- A hozzászóláshoz be kell jelentkezni
Küldjétek már el akár magánba is hogy ki volt ez a tanár, régebben én is tartottam C labort infosoknak a Friedler-ék alá tartozva.
Csak kíváncsi vagyok hogy ki volt ez, ismerem-e.
- A hozzászóláshoz be kell jelentkezni
[quote:7f78bc4e78="8192Joco"]Elég jól felhivta rá a figyelmet ,hogy kerűljétek.
Hat ahogy a foszlanyokbol kihamoztam nem eppen, mivel itt is elso korben gcc bug-rol szolt a kerdes, amugy meg Microsoft C#/C++/C&& vagy mi a f\asz forditon MUKODIK... erted, ott jo!!! Akkor meg mi van??? :twisted: :twisted:
Szoval szerintem nem sok embernek tunt fel, hogy a dolog szarvashiba!!!!
Zsiraf
BTW: Ezeket kellene gyepalni nem a goto-t :-)
- A hozzászóláshoz be kell jelentkezni
[quote:78ae364856="szaszg"][quote:78ae364856="8192Joco"]Elég jól felhivta rá a figyelmet ,hogy kerűljétek.
Hat ahogy a foszlanyokbol kihamoztam nem eppen, mivel itt is elso korben gcc bug-rol szolt a kerdes, amugy meg Microsoft C#/C++/C&& vagy mi a f\asz forditon MUKODIK... erted, ott jo!!! Akkor meg mi van??? :twisted: :twisted:
Szoval szerintem nem sok embernek tunt fel, hogy a dolog szarvashiba!!!!
Nem! Nem szarvashiba! Szerintem....
A C a hatékonyabb kód írásának lehetővé tétele miatt teszi lehetővé ezt a játékot a kifejezés visszaadott értékével. De a C könyvek fel is hívják a veszélyekre a figyelmet: a konkrét kiértékelés sorrendjétől függhet az eredmény.
Ha egy fordító nem cserélgeti, vagy mindig ugyanúgy cserélgeti a kifejezések sorrendjét, akkor ugyanaz az eredmény lesz mindig. Különben más lehet.
Ilyen esetekben egyértelműen a programozó a hibás, aki ilyen félreérthető kódot ír. Szigorúbb nyelvekben ezt nem lehet megtenni, de én a C-ben pont azt szeretem, hogy lehet nagyon hatékony kódot írni az ilyen i++-os kifejezésekkel. Cserébe tőlem kíván nagyobb figyelmet.
Na persze, jobb, ha egy fordító olyan intelligens, hogy felfedezi a veszélyt és ilyenkor nem variálja a kiértékelési sorrendet optimalizációs célokból. Tudom, hogy a kisebbséghez tartozom, de én inkább azt mondom: a fordító ne legyen túl intelligens, elég, ha warningol a veszélyre (ezt meg is teszi), majd én eldöntöm, mit tegyek. Ha túl intelligens a fordító és helyettem eldönti, hogy mikor csereberéli a sorrendet, attól félek, a lefordított program, hatékonysága kerül veszélybe. És nekem az a fontos (olyan alkalmazásokat írok), még ha ez tőlem több időt és átgondoltabb kódolást igényel is.
- A hozzászóláshoz be kell jelentkezni
[quote:c5d0363763="kmARC"]Helló. Lenne itt egy probléma, amit még tanult kollegám, Antiemes sem ért.
Szóval a kód a következő:
[code:1:c5d0363763]#include <stdio.h>
int main(){
int t1[5]={1,2,3,4,0}, t2[5]={5,6,7,8,0}, t3[5]={0,0,0,0,0},i;
for (i=0;i<4;){
t3[i]=t1[i++];
t1[i]=t2[i--];
t2[i]=t3[i++];
}
for(i=0;i<4;i++)printf("%d ",t1[i]);
printf("\n");
for(i=0;i<4;i++)printf("%d ",t2[i]);
printf("\n");
for(i=0;i<4;i++)printf("%d ",t3[i]);
printf("\n");
return 0;
}[/code:1:c5d0363763]
Aztán:
[code:1:c5d0363763][kmarc] [$] gcc -o marklar marklar.c && ./marklar
1 6 7 8
1 6 7 8
1 6 7 8[/code:1:c5d0363763]
Majd:
[code:1:c5d0363763][kmarc] [$] gcc -O2 -o marklar marklar.c && ./marklar
6 7 8 0
5 0 1 2
0 1 2 3[/code:1:c5d0363763]
Állítólag Windows alatt valamilyen módon lefordítva ez a kód a t1[] és t2[] tömb elemeit cseréli fel. Várjuk az ötleteket, előre is kössz :-)
gcc-3.3.6. Ja, és persze Slackware linux. Antiemes szerint lehet, hogy ez a baj...
szvsz ez pl. hiba :
for (i=0;i<4;){
t3[i]=t1[i++];
t1[i]=t2[i--];
t2[i]=t3[i++];
}
azaz t1[i]=t2[i--] no ez i=0 eseten ugye t2[-1] -es cimzes lesz. de szigoruan szvsz ; mert pont ezek miatt inkabb pascalozom :D)
- A hozzászóláshoz be kell jelentkezni
[quote:3fda30d56d="hokuszpk"]
szvsz ez pl. hiba :
for (i=0;i<4;){
t3[i]=t1[i++];
t1[i]=t2[i--];
t2[i]=t3[i++];
}
azaz t1[i]=t2[i--] no ez i=0 eseten ugye t2[-1] -es cimzes lesz. de szigoruan szvsz ; mert pont ezek miatt inkabb pascalozom :D)
Nem egészen, mert az előző sorban van egy i++; Pont ez jelentette
számomra a kiinduló pontot, hogy a t0[0] elemhez soha nem
nyúlunk hozzá. A -1-es indexű elem írására olyan segfaultot
dobna, mint a ház.
- A hozzászóláshoz be kell jelentkezni
[quote:b814eeeddd="kmARC"][quote:b814eeeddd="nosy"]hi,
bar nem vagyok informatikus, de c-ben egy
foo[i]=bar[i++] jellegu kifejezesre
"undefined, unspecified" vagy
"implementation specific" jelzot szoktak
hasznalni az okosok. lehet vitazni hogy melyik (meg hogy
melyik mit is jelent). mindenesetre szamomra
ez azt jelenti hogy ne hasznaljuk a szerkezetet.
a hsznalata soran bekovetkezo furcsa dolgokat
megerteni meg a fordito forraskodja alapjan lehetne (talan).
udv, ncs
Ommm.. szerintem meg eleg elterjedt dolog a tomb[i++], stb. hasznalata, lasd pl.: mplayer, vagy akarmi forraskod. Kicsit rovidebbe, egyszerubbe teszi a progit. Minek tegyunk meg egy sort inkrementalasnak, ha azt az elozobn is el tudunk vegezni.
Hmm... Szemeket kinyitni!!! nem kene a lenyegen atsiklanod!!! tehat megegyszer: foo[i]=bar[i++];
tehat az lvalue-ban hasznalod azt a valtozot (i) amit a jobb oldalon valtoztatsz...!!!
Ez egyenerteku kb. azzal, amikor fuggveny hivasakor az argumentumok kozott szerepeltetnel i-t es --i-t is... A kerdes az, hogy i erteke MIKOR valtozik meg??? A te peldadnal megmaradva az lvalue-t(annak cimet) mikor szamolja ki a programod??? Erre csak nosy-t tudom idezni: "undefined, unspecified" vagy "implementation specific". Amugy mindengyik ugyanazt jelenti, csak mas szemszogbol... A szabvany nem ad utasitast, hogy melyik jon elobb, (lvalue (cime) vagy a i++) talan ezt jelenti hogy undefined ill. unspecified. Es ez azt is jelenti, hogy implementation specific :-). Sot mint lattad, ha a gcc optimalizalt, akkor mashogy szamolta, mint ha nem... Ennyi!!!![quote:b814eeeddd="kmARC"]
Kosz, hogy ennyien utananeztetek. Ezek szerint:
i) 3.3-as szeriaval mas a ketfajta forditas
ii) 3.4-essel nem mas
iii) 4.0-ssal sem mas
iv) windows alatt sem csereli meg a t1 es t2 tomb elemeit...:-) (egyetemi zh-feladat... ;-) )
Ezt tulkeppen szepen kiszaszeroltad, de a problema sajna a TE kododban van. Ki kellene javitanod!!!
Zsiraf
- A hozzászóláshoz be kell jelentkezni
Közelítsük meg másképp a problémát! Hogyan lehetne a tanár által
kívánt eredményt elérni, ha gcc-t használunk! Íme:
i=0;for( i=0;i<4; ) {t3[i++]=t1[i]; t1[--i]=t2[i]; t2[i]=t3[i++]; }
Minden optimalizációt és figyelmeztetést kikapcsoltam!
A ciklus t1[] és t2[] tömb elemeit megcseréli!
- A hozzászóláshoz be kell jelentkezni
[quote:a4e79e0d6a="mortella"]Küldjétek már el akár magánba is hogy ki volt ez a tanár, régebben én is tartottam C labort infosoknak a Friedler-ék alá tartozva.
Csak kíváncsi vagyok hogy ki volt ez, ismerem-e.
Esetleg nekem is elkuldhetnetek privibe, az egyetemen dolgozom, de nem oktatok, plane nem C-t :)
- A hozzászóláshoz be kell jelentkezni
Bassz, Meditor!
1) mi a francnak inicializalod ketszer az i-t 0-ra?
2) ertem a jo szandekot, de inkabb arra kene felhivni a figyelmet ezredszer is, hogy az ilyen kod HIBAS ! Ne szerepeljen [post|pre][de|in]kremens operator , es a valtozo (amin a leptetest vegrehajtod) 1-nel tobbszor ugyanazon utasitason belul, mert fordito- es optimalizacios beallitas fuggo a vegeredmeny.
Lehet a dolog jo addig, amig mindig csak X oprendszer Y forditojanak Z beallitasat hasznalod. De mi van, ha masik oprendszert, masik forditot vagy masik beallitast kell hasznalnod? SZIVAS!
Egyebirant:
a) ezert vannak jobb forditoknal warning-szint allitasi lehetosegek (erdekelne, hogy gcc -Wall mit ad akar az eredeti, akar a Te kododra)
b) normalis UNIX rendszerekben ezert van/volt a lint nevu portabilitas ellenorzo program (ezt tobbe-kevesbe a gcc -Wall helyettesiti)
- A hozzászóláshoz be kell jelentkezni
[quote:ad261aa340="meditor"][quote:ad261aa340="hokuszpk"]
szvsz ez pl. hiba :
for (i=0;i<4;){
t3[i]=t1[i++];
t1[i]=t2[i--];
t2[i]=t3[i++];
}
azaz t1[i]=t2[i--] no ez i=0 eseten ugye t2[-1] -es cimzes lesz. de szigoruan szvsz ; mert pont ezek miatt inkabb pascalozom :D)
Nem egészen, mert az előző sorban van egy i++; Pont ez jelentette
számomra a kiinduló pontot, hogy a t0[0] elemhez soha nem
nyúlunk hozzá. A -1-es indexű elem írására olyan segfaultot
dobna, mint a ház.
az igaz,de akkor is csuf kod ez.
no szamoljuk vegig papiron.
t3[0] = t1[0] ; +1 ; t1[1]=t2[1] ; -1 ; t2[0]=t3[0] ; +1
ezek utan
t1={16340} ; t2={16780} ; t3={10000}
t3[1] = t1[1] ; +1 ; t1[2]=t2[2] ; -1 ; t2[1]=t3[1] ; +1
t1={16740} ; t2={16780} ; t3={16000}
t3[2]=t1[2] ; +1 ; t1[3]=t2[3] ; +1 ; t2[2]=t3[2]; +1
t1={16780} ; t2={16780} ; t3={16700}
stb. szoval az 1678 1678 1678 szvsz ez a jo.
masik verzio
t3[0] = t1[i+1] ; t1[1] = t2[i-1] ; t2[0]=t3[i+1]
t3[0] = 2 ; t1[1]=5 ; t2[0]=1 ; i=1
azaz t3={20000} t1={15340} t2={
t3[1] = t1[i+1] ; t1[2]=t2[i-1] ; t2[1]=t3[i+1]
t3[1] = 3 ; t1[2]=6 ; t2[
no ez itt megbukott.
harmadik verzio:
t3[i] = t1[i+1] no ebbol szvsz az ms fordito meg az optimalizacio ezt csinal(hat)ja :
{
i++ ; t3[i] = t1[i]
ekkor t3={01000}...
i-- ; t1[i] = t2[i]
t1={52340}
i++ ; t2[i]= t3[i]
t2={50780}
hm. ez majdnem jo az optim gcc meg az ms c eredmenyere. de megsenem.
na jo. ha veletlenul c-ben kell alkotnom,akkoris inkabb szetbontom; nemvagyok hajlando meg azon is gondolkodni,hogy mitcsinal az optimalizacio meg meg vegyem figyelembe az adott C forditot is...
- A hozzászóláshoz be kell jelentkezni
[quote:69a3d1b514="horvatha"]
Nem! Nem szarvashiba! Szerintem....
[quote:69a3d1b514="horvatha"]Ilyen esetekben egyértelműen a programozó a hibás, aki ilyen félreérthető kódot ír.
Na most ezt a kettőt így együtt nem értem...
[quote:69a3d1b514="horvatha"]Na persze, jobb, ha egy fordító olyan intelligens, hogy felfedezi a veszélyt és ilyenkor nem variálja a kiértékelési sorrendet optimalizációs célokból.
Mihez képest nem variálja, ha egyszer a nyelv specifikációja nem határozza meg a sorrendet? Gyakorlatilag azt csinál, amit akar, teljesen függetlenül az optimalizációtól.
KisKresz
- A hozzászóláshoz be kell jelentkezni
Hi!
Az a szomoru, hogy itt a Veszpremi Egyetemen igy 'oktatjak' a C-t.
By(t)e
TBS::Antiemes
- A hozzászóláshoz be kell jelentkezni
[quote:9a008342ef="meditor"]Ha a programot átalakítom így:
for( i=0;i<4; ) {t3[i]=t1[i];i++; t1[i]=t2[i];i--; t2[i]=t3[i];i++;}
mely kód ELMÉLETILEG equivalens az eredetivel (postinkremens index),
Hoppa! Epp az a baj, hogy nem ekvivalens, meg elmeletileg sem... Amint azt mar tobben is leirtak, egy ilyen kifejezes, mint
[code:1:9a008342ef]t3[i] = t1[i++][/code:1:9a008342ef]
nem ekvivalens azzal, hogy
[code:1:9a008342ef]t3[i] = t1[i]; i++;[/code:1:9a008342ef]
mert fugg a kiertekeles sorrendjetol: a jobb vagy baloldal ertekelodik ki hamarab.... Huha ez a sok jobb-baloldalazas mar mindjart politikai hangszint ad az egesznek :D
- A hozzászóláshoz be kell jelentkezni
[quote:b0c53d954e="meditor"][quote:b0c53d954e="KisKresz"][quote:b0c53d954e="meditor"]A lokális változó esetében a változó
nem lapozódik ki a memóriából
Tessék?
KisKresz
Más szavakkal: a változó értéke két függvényhívás közt is megmarad.
Ha nem static, akkor minden fvhívásnál újból és újból lefoglalódik
a lokális változó, újra kell inícializálni, és a végén a változó helye
felszabadul.
Függvény vagy blokk. :-)
KisKresz
- A hozzászóláshoz be kell jelentkezni
[quote:e4137ffa90="1aca"][quote:e4137ffa90="meditor"]Ha a programot átalakítom így:
for( i=0;i<4; ) {t3[i]=t1[i];i++; t1[i]=t2[i];i--; t2[i]=t3[i];i++;}
mely kód ELMÉLETILEG equivalens az eredetivel (postinkremens index),
Hoppa! Epp az a baj, hogy nem ekvivalens, meg elmeletileg sem... Amint azt mar tobben is leirtak, egy ilyen kifejezes, mint
[code:1:e4137ffa90]t3[i] = t1[i++][/code:1:e4137ffa90]
nem ekvivalens azzal, hogy
[code:1:e4137ffa90]t3[i] = t1[i]; i++;[/code:1:e4137ffa90]
mert fugg a kiertekeles sorrendjetol: a jobb vagy baloldal ertekelodik ki hamarab.... Huha ez a sok jobb-baloldalazas mar mindjart politikai hangszint ad az egesznek :D
Jaja, nem ekvivalens, közben rájöttem, illetve VAN olyan
fordítóértelmezés, amelyben ekvivalens. Inkább azt akartam
írni, hogy a feladat megfogalmazója arra gondolhatott, amit
az én újraértelmezett kódom is tartalmaz, hacsak nem direkt
szívatta a diákokat. Azaz vagy butaság volt ezt a feladatot
kiadni, vagy gonoszság. Lehet választani.
- A hozzászóláshoz be kell jelentkezni
[quote:33a0a442c5="meditor"]
Jaja, nem ekvivalens, közben rájöttem, illetve VAN olyan
fordítóértelmezés, amelyben ekvivalens. Inkább azt akartam
írni, hogy a feladat megfogalmazója arra gondolhatott, amit
az én újraértelmezett kódom is tartalmaz, hacsak nem direkt
szívatta a diákokat. Azaz vagy butaság volt ezt a feladatot
kiadni, vagy gonoszság. Lehet választani.
Hacsak a valaszok kozott nem volt egy olyan, hogy "meghatarozatlan", akkor butasag volt. Es nem lepne meg...
- A hozzászóláshoz be kell jelentkezni
[quote:fc48f4d888="1aca"][quote:fc48f4d888="meditor"]
Jaja, nem ekvivalens, közben rájöttem, illetve VAN olyan
fordítóértelmezés, amelyben ekvivalens. Inkább azt akartam
írni, hogy a feladat megfogalmazója arra gondolhatott, amit
az én újraértelmezett kódom is tartalmaz, hacsak nem direkt
szívatta a diákokat. Azaz vagy butaság volt ezt a feladatot
kiadni, vagy gonoszság. Lehet választani.
Hacsak a valaszok kozott nem volt egy olyan, hogy "meghatarozatlan", akkor butasag volt. Es nem lepne meg...
Tényleg érdekelne mi a helyes megoldás - a tanár szerint.
- A hozzászóláshoz be kell jelentkezni
[quote:a889744a13="szaszg"]Ezt tulkeppen szepen kiszaszeroltad, de a problema sajna a TE kododban van. Ki kellene javitanod!!!Zsiraf
Nem is állítottam magmaról, hogy guru vagyok, de még egyszer mondom, a kód nem az enyém, hanem egy elborult magát c-compilernek képzelő tanáré. Mint ahogyan az fentebb leírtam.
A topic lényege, pedig az, hogy miért futott kétféle fordításból kétféleképpen a cucc.
Szóval a probléma nem az ÉN kódomban van, mert az nem szerepel itt.
Ragozzam még...? :-)
A tanár szerint (akié a kód ugyebár, merthogy a kód nem az enyém...) a cucc megcseréli a t1 és t2 tömb elemeit.
Sőt, ma ZH előtt egy srác jött, mondta, hogy mittoménmilyen visual c/c++ M$ sucking framework akármi alatt lefordította, és neki megcserélte.
Én egyértelműen a kód (amely nem az enyém) hibája mellett foglalok állást.
Esetleg valaki más architektúrán lefordítaná? Köszi... :-)
- A hozzászóláshoz be kell jelentkezni
[quote:74d9d1d62d="Zahy"]Bassz, Meditor!
1) mi a francnak inicializalod ketszer az i-t 0-ra?
2) ertem a jo szandekot, de inkabb arra kene felhivni a figyelmet ezredszer is, hogy az ilyen kod HIBAS ! Ne szerepeljen [post|pre][de|in]kremens operator , es a valtozo (amin a leptetest vegrehajtod) 1-nel tobbszor ugyanazon utasitason belul, mert fordito- es optimalizacios beallitas fuggo a vegeredmeny.
Lehet a dolog jo addig, amig mindig csak X oprendszer Y forditojanak Z beallitasat hasznalod. De mi van, ha masik oprendszert, masik forditot vagy masik beallitast kell hasznalnod? SZIVAS!
Egyebirant:
a) ezert vannak jobb forditoknal warning-szint allitasi lehetosegek (erdekelne, hogy gcc -Wall mit ad akar az eredeti, akar a Te kododra)
b) normalis UNIX rendszerekben ezert van/volt a lint nevu portabilitas ellenorzo program (ezt tobbe-kevesbe a gcc -Wall helyettesiti)
Hello Zahy! Nem kell az i-t kétszer inícializálni, teljesen igazad van.
Egy korábbi hozzászólásomban említettem is, hogy a for ciklus
feje inícializálja az i-t. Azt is említettem, hogy -Wall-ra nyávogás van,
(i maybe undefinied). Egyébiránt ha már állásfoglalásra késztettél ez ügyben:
NEM A KÓD A ROSSZ! A kód jó, csak hordozhatatlan. A programozó
a hordozhatóság elemi szabályait sem tartotta be, de ezért nem
a kód a hibás, kód csinálja amit kell hol ezt, hol azt (-::
Szóval véleményem szerint, aki felhasználói programban ilyen
megoldást választ, az vagy nagyon tapasztalatlan, vagy nagyon bátor,
hogy azt ne mondjam vakmerő és biztos nem a paksi atomerőmű
szabályozórendszerét kódolja.
- A hozzászóláshoz be kell jelentkezni
[quote:53eccae9d3="meditor"]NEM A KÓD A ROSSZ! A kód jó, csak hordozhatatlan.
Szerintem a kód rossz. Nem attól lesz jó, hogy lefordul, hanem ha a szabvány szerint azt csinálja, amit szeretnél. Tudok mutatni olyan rossz kódot, amire még csak nem is warningol -Wall-nál sem:[code:1:53eccae9d3]int a = a;
printf ("%d\n",a)[/code:1:53eccae9d3]Ez szerinted jó kód? Pedig lefuttattam egypárszor egymás után, és nekem mindig 134513680-t írt ki. Szerinted erre a működésre így lehet építeni egy program fejlesztésekor?
- A hozzászóláshoz be kell jelentkezni
[quote:45b4bcc66a="meditor"]
NEM A KÓD A ROSSZ! A kód jó, csak hordozhatatlan. A programozó
a hordozhatóság elemi szabályait sem tartotta be, de ezért nem
a kód a hibás, kód csinálja amit kell hol ezt, hol azt (-::
Szóval véleményem szerint, aki felhasználói programban ilyen
megoldást választ, az vagy nagyon tapasztalatlan, vagy nagyon bátor,
hogy azt ne mondjam vakmerő és biztos nem a paksi atomerőmű
szabályozórendszerét kódolja.
A kód humánparserrel :) feldolgozva jó, bármilyen ettől eltérő felhasználása (valamilyen C-fordítónak odaadva) során a lefordított kód kimenete a fordító működésétől függgően eltérő lehet, azaz a fordítás nem hajtható végre egyértelműen, a kódról nem mondható meg, hogy lefordítva mit csinál, csak az, hogy aki írta, mit szeretne, hogy csináljon.
- A hozzászóláshoz be kell jelentkezni
O.K. Definiáljuk a jó kódot, aztán folytassuk az egyébként akadémikus
vitát. Épeszű ember nyilván nem ad ki olyan kódot a kezéből, mint
amilyen pl a vita alapját képező kód. Fentartom azt a véleményem,
hogy a kérdéses kód mind szintaktikailag, mind szemantikailag jó.
Ugyanabban a környezetben tetszőleges számú futás mindig ugyanazt
az eredményt adja és amennyiben az input megfelel a kívánalmaknak,
egy rossz szót sem lehet rá mondani. Illetve egyet mégis: hordozhatatlan.
- A hozzászóláshoz be kell jelentkezni
[quote:0158ca3b63="zebra"]Pedig lefuttattam egypárszor egymás után, és nekem mindig 134513680-t írt ki.
Tényleg nem warningol, gcc 3.3.4 és 4.0.2 sem. Ez elég gáz. Viszont nekem mindig mást ír ki, de csupa -1208340492 körüli számot. :-)
- A hozzászóláshoz be kell jelentkezni
[quote:7350dd9b43="1aca"][quote:7350dd9b43="meditor"][quote:7350dd9b43="Zahy"][quote:7350dd9b43="meditor"][quote:7350dd9b43="KisKresz"][quote:7350dd9b43="meditor"]A lokális változó esetében a változó
nem lapozódik ki a memóriából
Tessék?
KisKresz
Más szavakkal: a változó értéke két függvényhívás közt is megmarad.
Ha nem static, akkor minden fvhívásnál újból és újból lefoglalódik
a lokális változó, újra kell inícializálni, és a végén a változó helye
felszabadul.
Azért valljuk be, ez azért nem ugyanaz :-) Mellesleg megnéztem a kezdeti barom kódot FreeBSD alatt, és gcc 3.4.4 és a legutolsó TenDRA fordító -tök_ ugyanazt a marhaságot állította elő. Az "int a=a" kód legalább más kimenetet generált e két fordítóval :-)
Na jó, nem ugyanaz (-:: , de én legalább nem tanítom!
Nem, de hangoztatod.. Ami majdnem ugyanaz :D
Azért nem egészen, mert egy fórumon, ha valaki jobban tudja,
mint az előző közlő, nyugodtan kontrázhat. Próbáld meg
ezt egy fizetése által frusztrált tanárral!
- A hozzászóláshoz be kell jelentkezni
[quote:91a1fd881a="kmARC"]
A tanár szerint (akié a kód ugyebár, merthogy a kód nem az enyém...) a cucc megcseréli a t1 és t2 tömb elemeit.
Sőt, ma ZH előtt egy srác jött, mondta, hogy mittoménmilyen visual c/c++ M$ sucking framework akármi alatt lefordította, és neki megcserélte.
Én egyértelműen a kód (amely nem az enyém) hibája mellett foglalok állást.
Esetleg valaki más architektúrán lefordítaná? Köszi... :-)
A kod tenyleg hibas.. Es ez nem architektura vagy compiler verzio kerdese, vagy esetleg optimizacios flag-ek hasznalatae... Hanem a C nyelv szabalyai miatt. Ahol benne van tisztan, hogy egy kifejezesben az al-kifejezesek kiertekelesi sorrendje nem meghatarozott, implementacio-fuggo. Es ez szvsz a C nyelv egyik erossege, ez az egyik ok, amiert lehet optimizalo (vagy optimalizalo?) compilereket irni.
- A hozzászóláshoz be kell jelentkezni
[quote:03c78cf0a1="meditor"]Ugyanabban a környezetben tetszőleges számú futás mindig ugyanazt
az eredményt adja és amennyiben az input megfelel a kívánalmaknak,
egy rossz szót sem lehet rá mondani. Illetve egyet mégis: hordozhatatlan.
s/input/output/ gondolom ezt akartad írni.
A kód nemcsak hordozhatatlan, amit fent írtál, hogy "ugyanabban a környezetben" mindig ugyanazt csinálja, az valóban teljesül, de egy szoftverfejlesztés során nem szabad támaszkodnod arra, hogy mindig ugyanaz lesz a környezet. Lehet hogy egy bug miatt frissítesz epszilonnal újabb c-fordítóra vagy akár csak egy apró patchet alkalmazol, és máris (teljesen jogosan) másmilyen outputot készít a fordítód. A szóban forgó forráskód, mint már többen nagyon helyesen kivesézték, nem egyértelmű, többféleképp is lehet értelmezni, a "humánparser"-rel feldolgozva is többértelmű. A C nyelv specifikációjában minden bizonnyal szerepel említés, hogy az ilyen esetek nem egyértelműek. A fordítód specifikációjában minden bizonnyal nem szerepel dokumentálva, hogy az ilyen esetekben mit csinál.
Innen kezdve pedig hülyeség menteni a menthetőt a süllyedő hajóról, igenis ki kell mondani egyenesen: nem dokumentált viselkedésre (sőt, dokumentáltan hibás szituációra pláne) támaszkodni _hiba_, a forráskód tehát _hibás_.
Mellesleg (szerintem) egy c fordítónak akár arra is joga van, hogy random generálja kedve szerint az egyik lehetséges outputot, illetve talán arra is, hogy olyan kódot generáljon, ami runtime random módon az egyik értelmezést hajtja végre. Nyilván persze senki nem csinál ilyet, itt elvről van szó.
- A hozzászóláshoz be kell jelentkezni
[quote:a83d99d707="KisKresz"][quote:a83d99d707="meditor"][quote:a83d99d707="KisKresz"][quote:a83d99d707="meditor"]A lokális változó esetében a változó
nem lapozódik ki a memóriából
Tessék?
KisKresz
Más szavakkal: a változó értéke két függvényhívás közt is megmarad.
Ha nem static, akkor minden fvhívásnál újból és újból lefoglalódik
a lokális változó, újra kell inícializálni, és a végén a változó helye
felszabadul.
Függvény vagy blokk. :-)
KisKresz
Véleményem szerint mindannyian tudjuk mi a jelenség, a
terminológiáról vitatkozunk, ha ugyan vitának lehet ezt nevezni.
Rosszul használtam egy két fogalmat bocs. Elismerem, hogy a tudásom
nem akadémikus.
- A hozzászóláshoz be kell jelentkezni
[quote:1a8156c3f3="meditor"]O.K. Definiáljuk a jó kódot, aztán folytassuk az egyébként akadémikus
vitát. Épeszű ember nyilván nem ad ki olyan kódot a kezéből, mint
amilyen pl a vita alapját képező kód. Fentartom azt a véleményem,
hogy a kérdéses kód mind szintaktikailag, mind szemantikailag jó.
Ugyanabban a környezetben tetszőleges számú futás mindig ugyanazt
az eredményt adja és amennyiben az input megfelel a kívánalmaknak,
egy rossz szót sem lehet rá mondani. Illetve egyet mégis: hordozhatatlan.
Nem, a hodozhatatlan az, ha mondjuk ezt írom:
[code:1:1a8156c3f3]__int64 a;[/code:1:1a8156c3f3]Lesznek olyan fordítók, amiknél teljesen helyesen működik, és lesznek olyanok, amik nem ismerik ezt a típust (illetve nem ezen a néven). Ez a hordozhatatlan. Az f(i++,i) nem hordozhatatlan, hanem nem definiált sehol sem. Rossz. Minden valamirevaló C könyvben le an írva, hogy ezt így nem szabad használni.
- A hozzászóláshoz be kell jelentkezni
[quote:0f0bece9a8="zeller"]A kód humánparserrel :) feldolgozva jó
Ha "humánparserrel" feldolgozva jó lenne, akkor a C-fordítóknak is gyerekjáték lenne feldolgozni jól. Itt arról van szó, hogy már kézzel megemésztve az utasításokat sem egyértelmű azok jelentése, innen kezdve a C-fordítónak sincs sok esélye a nemdefiniált "helyes" működésű kód előállítására.
- A hozzászóláshoz be kell jelentkezni
[quote:1864443241="szaszg"]amugy meg Microsoft C#/C++/C&& vagy mi a f\asz forditon MUKODIK... erted, ott jo!!! Akkor meg mi van???
gcc-n is működik, az is csinál valamit, és azt kéne már megértened, hogy maga a FORRÁSKÓD értelmezhető többféleképpen, és sem a gcc, sem az msc nem gondolatolvasó, így ha mást-mást is generálnak, egyikre sem mondhatod hogy jó vagy hogy rossz. Ma még nem tart ott a számítástechnika, hogy te leírod többértelmű módon a gondolataidat, és a gép kitalálja, hogy melyikre gondoltál a több lehetséges értelmezés közül.
Vagyis: amit a gcc generál, az se nem jó, se nem rossz. Amit az msc generál, az se nem jó, se nem rossz. A forráskód, az rossz.
- A hozzászóláshoz be kell jelentkezni
[quote:19f78367cb="egmont"][quote:19f78367cb="zebra"]Pedig lefuttattam egypárszor egymás után, és nekem mindig 134513680-t írt ki.
Tényleg nem warningol, gcc 3.3.4 és 4.0.2 sem. Ez elég gáz. Viszont nekem mindig mást ír ki, de csupa -1208340492 körüli számot. :-)
nyilvan azt írja ki, amit egy definiálatlan memóriacimen talál.
Amikor azt mondod: int a - akkor lefoglal egy memóriacímet "a"-nak és
amikor ezt egyenlővé teszed önmagával, akkor az "a" értékét egyenlővé
tetted az "a" címe alatt található integerként értelmezett 32 bittel. Ezzel
semmi probléma nincs, de a fordító azért -Wall-ra szólhatna valamit.
- A hozzászóláshoz be kell jelentkezni
Hát szerintem a tanárodnak mutasd meg ezt a topic-ot. Mondván E-tréning keretén belűl Egmont összegezte az eredményt. Egyest tán nem add elvégre a témával nem csak foglalkoztál hanem másokat is aktivan elgondolkodtatál rajta.
- A hozzászóláshoz be kell jelentkezni
Hadd dobjam fel a topicot egy hasonló jellegű, ámde nem iskolapadból, hanem valós életből vett problémával.
Az UHU-ban most próbálunk átállni jelenlegi 3.3-as gcc-ről 4-esre. Elég messze vagyunk még ettől sajnos, még egy csomó programot meg kell patchelni, hiszen a 4-es (szokás szerint) szigorúbb a 3.3-asnál. Nem tudom, hogy alant ecsetelt szigorítás a 3.4-esben megjelent-e már, vagy a 4.0 újdonsága, de nem is ez a lényeg.
Több tucat programmal találkoztunk már, ahol a gcc 4.0 azzal a hibaüzenettel szállt el, hogy egy korábban nem statikusnak deklarált változó vagy függvény később statikusnak volt deklarálva.
Példa:
common.h tartalmaz ilyet:
extern int foobar; /* deklaraljuk a foobar változót */
a legtöbb .c fájl így fest:
#include "common.h"
/* aztán később vagy használja a foobar változót, vagy nem */
persze az egyik .c fájl nemcsak deklarálja, hanem definiálja is a változót:
#include "common.h"
int foobar;
de a marklar.c fájlban váratlan meglepetésként ez áll:
#include "common.h"
static int foobar;
/* majd persze használja is később a foobar-t */
Szokás szerint a .c fájlokból egyenként .o készül, amik végül összelinkelődnek a végeredmény binárissá.
Na ezt a 3-as gcc lefordította, működött a program. A 4-es (szerintem teljesen jogosan) elszáll azzal, hogy a marklar.c emésztése során először (közvetve, a common.h-ban) azt mondtuk, hogy a foobar egy közös globális változó, majd később (közvetlenül a marklar.c-ben) azt, hogy csak a marklar.c-n belül létező statikus változó, és ez a kettő ellentmond egymásnak.
Találós kérdés következik:
Adott több tucat program, mindegyik valahogy ilyesmi felépítésű, amik nem fordulnak az új gcc-vel. Túl sok program, túl nagyok, egyiket sem mi írtuk, tehát nincs arra idő, hogy megértsük, mit is csinál pontosan a forrás. Mindössze az a feladat, hogy minél gyorsabban megpatcheljük őket, hogy az új gcc-vel is leforduljon, és pontosan ugyanúgy működjön, mint eddig. Szerintetek hogyan kell ezt megtenni?
(Félreértések elkerülése végett: nem segítséget kérek a fejlesztéshez, az adott programokat már megpatcheltük, csak kíváncsi vagyok, hogy ki hogyan csinálná. Én tudok jó és rossz lehetséges válaszokat is.)
- A hozzászóláshoz be kell jelentkezni
Félreértés ne essék, én nem védem a kritika tárgyát és nem védem a
tanárt sem. Törjön le a kezem, ha ilyen incrementálást/decrementálást
használnék! DE! én azt hiszem ránézésre nagyon nehéz eldönteni egy
kódról, hogy jó-e. Ehhez ismerni kell a programozó szándékait.
Az idézett indexelés lehetne akár a C nyelv és egy a köréje épített
rendszer ismeretének magasiskolája.
Igenis sokszor csinálunk nagyon felesleges dolgokat, mert nem ismerjük
elég jól sem a nyelvet, sem a környezetet. Az én mondanivalom e
vitában mindössze ennyi.
egmontnak: természetesen outputot akartam írni.
- A hozzászóláshoz be kell jelentkezni
[quote:f442908c28="meditor"]nyilvan azt írja ki, amit egy definiálatlan memóriacimen talál.
Amikor azt mondod: int a - akkor lefoglal egy memóriacímet "a"-nak és
amikor ezt egyenlővé teszed önmagával, akkor az "a" értékét egyenlővé
tetted az "a" címe alatt található integerként értelmezett 32 bittel. Ezzel
semmi probléma nincs, de a fordító azért -Wall-ra szólhatna valamit.
Teljesen tiszta, ebben teljesen egyetértünk.
- A hozzászóláshoz be kell jelentkezni
[quote:9aa9428c7a="egmont"][quote:9aa9428c7a="meditor"]nyilvan azt írja ki, amit egy definiálatlan memóriacimen talál.
Amikor azt mondod: int a - akkor lefoglal egy memóriacímet "a"-nak és
amikor ezt egyenlővé teszed önmagával, akkor az "a" értékét egyenlővé
tetted az "a" címe alatt található integerként értelmezett 32 bittel. Ezzel
semmi probléma nincs, de a fordító azért -Wall-ra szólhatna valamit.
Teljesen tiszta, ebben teljesen egyetértünk.
És miben nem? (-::
No, a példád az fordításkor akad ki, vagy linkeléskor?
- A hozzászóláshoz be kell jelentkezni
[quote:712f182626="egmont"][quote:712f182626="zebra"]Pedig lefuttattam egypárszor egymás után, és nekem mindig 134513680-t írt ki.
Tényleg nem warningol, gcc 3.3.4 és 4.0.2 sem. Ez elég gáz. Viszont nekem mindig mást ír ki, de csupa -1208340492 körüli számot. :-)
Kedves Egmont, ez csak annyit jelent, h olyan oprendszert/C-compilert hasznalsz, ami valamilyen stack-attack elleni vedelmet hasznal.
E fenti ominozus kod rossz, mert nalam viszont konstans -1077941840 erteket ad; pedig szerintem ha "a"-nak a erteket adom, akkor a erteket kene kapjam. Viszont a erteke 0x61, ami testverek kozott is 97, nem pedig boszme nagy negativ szam. :-D
Visszaterve az eredeti problemara, valaki (esetleg a topicnyito) megtehetne, hogy az oktato oprendszerkornyezeteben (Win?) kiprobalna _par_ kulonbozo C forditot. Nyilvan lehet talalni MS, Borland, GNU, Intel, Lahey stb kompilereket, ha valaki nagyon keres. Telepites, kod leforditasa, eredmeny papiralapon oktato orra ele pakolasa. Ha esetleg _mind_ ugyanazt a (fene se tudja) milyen kimenetet adja, akkor ide kuldje be az eredmenyt. Esetleg azt is meg lehetne tenni, hogy ha valakinek van pl. Intel ICC-je feltelepitve a Linuxan, vagy esetleg egy Tendra, vagy mas C-compiler, akkor ugyanazon a nem ma$ oprendszeren is leforditani es ellenorizni az eredmenyt.
OT: jo-e az alabbi kod:
main() {
printf( &unix[ "\021%six\012\0" ], (unix) [ "have" ] + "fun" - 0x60 );
}
A kod az www.ioccc.org -rol valo, ha jol emlekszem jot.c neven talalhato meg, es mukodese UNIX(-like) es ASCII-kodtablat hasznalo rendszert feltetelez. (Megjegyzes:
1) AIX-en utoljara X eve neztem, es megallapitottam, az nem UNIX ;-)
2) a mukodesre vonatkozo ket megjegyzes a kod erthetoseget nagy mertekben elosegiti.
Megjegyzes vege.)
Remelem a vacak portalmotor nem nyel le semmit a kodbol.
- A hozzászóláshoz be kell jelentkezni
[quote:6d364116b1="meditor"]DE! én azt hiszem ránézésre nagyon nehéz eldönteni egy
kódról, hogy jó-e. Ehhez ismerni kell a programozó szándékait.
Az idézett indexelés lehetne akár a C nyelv és egy a köréje épített
rendszer ismeretének magasiskolája.
Az előbb akartam már válaszolni, amikor a helyes kód definícióját kérted, aztán rájöttem, hogy nem vállalkoznék rá. Túl bonyolult kérdés. De most talán mégis teszek egy próbát. Használható definíciót ne várjon senki, pusztán eszmefuttatás.
Szóval totál igazad van abban, hogy helyes kód az, ami egybeesik a programozó szándékával (azt csinálja amit a kódolója akart hogy csináljon). Ez egy dolog. Másik dolog, hogy mindemellett az sem árt, ha valami értelmes dolgot csinál, és egybeesik a felhasználó képzeteivel, például ha valaki ír egy md5-számolót, ami szándékosan szart számol, akkor lekódolta azt amit akart, viszont mégsem jó, mert nem az, amit a felhasználó elvárna.
Na ez persze egy roppant messzi megközelítés volt. A másik irányból megközelítve nyilván a körülötte lévő infrastruktúra (fordító, függvénytárak, oprendszer) stb. is része a kérdéskörnek. Ha például azt mondom, hogy #include <conio.h>, akkor az DOS alatt lehet helyes, de Unix alatt aligha lesz az.
Hasonló módon ha én például gcc-specifikus kiterjesztéseket használok, akkor az helyes kód vagy sem? Attól függ, hogy célom-e portolni másmilyen fordítókra.
Ha történetesen az lenne a helyzet, hogy ilyen-olyan okok miatt gcc-specifikus kódot írnék, ezt dokumentálnám, sőt biztossá tenném hogy más C-fordítónak esélye sincs lefordítani, ÉS tegyük fel a gcc dokumentációjában le lenne írva, hogy az a[i]=b[i++] típusú utasításokat a gcc hogyan értelmezi, és én is ennek megfelelően használnám, akkor azt mondanám, hogy nem szép, nem szép, húzom a szám szélét, de belemegyek hogy az adott környezetre tett megszorításokkal élve a kód helyes.
De továbbra is tartom, hogy ha kihasználom a gcc egy dokumentálatlan tulajdonságát, ami most épp úgy tűnik hogy így van, de nem tudhatom hogy melyik pillanatban lesz másképp vagy melyik gcc-kapcsoló eredményezi azt hogy másképp lesz lefordítva, nos ebben a pillanatban szerintem a kód már hibás.
Hasonló: ZX Spectrumon és előbb-utóbb ennek megfelelően a Z80 assembly-jén nőttem fel, kódoltam asm-ben csomót, volt idő hogy szinte fejből tudtam az utasítások hexa kódját, időigényét és jelzőbitekre tett mellékhatásait is. Volt pár nem dokumentált kód, olyan byte-ok, melyekre a doksi nem írta le, hogy mit csinál a Z80 processzor. Én nem tudtam hogy mit csinál. A nálam is komolyabb Z80-azók tudták azokat is, sőt néha ki is használták, talán még olyan kód is akadt köztük, amelyik tényleg gyorsabban csinált meg valamit, mintha csak dokumentált utasításokból építkeztünk volna. Vajon helyes az ezeket kihasználó kód? Vajon miért döntött úgy a Zilog, hogy nem dokumentálja azon utasítások viselkedését? Talán azért, mert fenntartotta magának a jogot, hogy akár Z80 néven később olyan processzort hozzon ki, ami ezekre a kódokra mást csinál. Vagy éppen ez volt a továbbfejlesztésre szánt slot, későbbi Z80-nal felülről kompatibilis processzorba ide rakták be az új utasításokat. Nos, ezek alapján helyes egy olyan kód, amelyik használ ilyen utasításokat is? Véleményem szerint: ha azt mondom, hogy arra a konkrét Z80 processzorra írtam, ami itt van a kezemben, akkor helyes, hiszen lásd, működik. Ha azt mondom, hogy Z80-ra írtam (úgy általában), akkor még ha ebben a pillanatban a világ összes Z80-asa is jól hajtja végre, akkor sem helyes, mert lehet hogy ami holnap jön ki a gyárból, az (bármiféle figyelmeztetés nélkül) már hülyeséget fog csinálni.
- A hozzászóláshoz be kell jelentkezni
Kedves Zahy!
szerintem ez a két dolog nem egyenlő C alatt:
int a = a; illetve int a = 'a';
- A hozzászóláshoz be kell jelentkezni
[quote:e9d89bfa15="meditor"]No, a példád az fordításkor akad ki, vagy linkeléskor?
A marklar.c fájl fordításakor.
- A hozzászóláshoz be kell jelentkezni
[quote:d75955dbd7="Zahy"]OT: jo-e az alabbi kod: ... stb ...
Remelem a vacak portalmotor nem nyel le semmit a kodbol.
Mielott tobben anyazni kezdenetek, ne, nem nyelt le semmit, a kod ugy van, ahogy fentebb latszik.
- A hozzászóláshoz be kell jelentkezni
[quote:b0dc29136f="egmont"][quote:b0dc29136f="meditor"]DE! én azt hiszem ránézésre nagyon nehéz eldönteni egy
kódról, hogy jó-e. Ehhez ismerni kell a programozó szándékait.
Az idézett indexelés lehetne akár a C nyelv és egy a köréje épített
rendszer ismeretének magasiskolája.
Az előbb akartam már válaszolni, amikor a helyes kód definícióját kérted, aztán rájöttem, hogy nem vállalkoznék rá. Túl bonyolult kérdés. De most talán mégis teszek egy próbát. Használható definíciót ne várjon senki, pusztán eszmefuttatás.
Szóval totál igazad van abban, hogy helyes kód az, ami egybeesik a programozó szándékával (azt csinálja amit a kódolója akart hogy csináljon). Ez egy dolog. Másik dolog, hogy mindemellett az sem árt, ha valami értelmes dolgot csinál, és egybeesik a felhasználó képzeteivel, például ha valaki ír egy md5-számolót, ami szándékosan szart számol, akkor lekódolta azt amit akart, viszont mégsem jó, mert nem az, amit a felhasználó elvárna.
Na ez persze egy roppant messzi megközelítés volt. A másik irányból megközelítve nyilván a körülötte lévő infrastruktúra (fordító, függvénytárak, oprendszer) stb. is része a kérdéskörnek. Ha például azt mondom, hogy #include <conio.h>, akkor az DOS alatt lehet helyes, de Unix alatt aligha lesz az.
Hasonló módon ha én például gcc-specifikus kiterjesztéseket használok, akkor az helyes kód vagy sem? Attól függ, hogy célom-e portolni másmilyen fordítókra.
Ha történetesen az lenne a helyzet, hogy ilyen-olyan okok miatt gcc-specifikus kódot írnék, ezt dokumentálnám, sőt biztossá tenném hogy más C-fordítónak esélye sincs lefordítani, ÉS tegyük fel a gcc dokumentációjában le lenne írva, hogy az a[i]=b[i++] típusú utasításokat a gcc hogyan értelmezi, és én is ennek megfelelően használnám, akkor azt mondanám, hogy nem szép, nem szép, húzom a szám szélét, de belemegyek hogy az adott környezetre tett megszorításokkal élve a kód helyes.
De továbbra is tartom, hogy ha kihasználom a gcc egy dokumentálatlan tulajdonságát, ami most épp úgy tűnik hogy így van, de nem tudhatom hogy melyik pillanatban lesz másképp vagy melyik gcc-kapcsoló eredményezi azt hogy másképp lesz lefordítva, nos ebben a pillanatban szerintem a kód már hibás.
Hasonló: ZX Spectrumon és előbb-utóbb ennek megfelelően a Z80 assembly-jén nőttem fel, kódoltam asm-ben csomót, volt idő hogy szinte fejből tudtam az utasítások hexa kódját, időigényét és jelzőbitekre tett mellékhatásait is. Volt pár nem dokumentált kód, olyan byte-ok, melyekre a doksi nem írta le, hogy mit csinál a Z80 processzor. Én nem tudtam hogy mit csinál. A nálam is komolyabb Z80-azók tudták azokat is, sőt néha ki is használták, talán még olyan kód is akadt köztük, amelyik tényleg gyorsabban csinált meg valamit, mintha csak dokumentált utasításokból építkeztünk volna. Vajon helyes az ezeket kihasználó kód? Vajon miért döntött úgy a Zilog, hogy nem dokumentálja azon utasítások viselkedését? Talán azért, mert fenntartotta magának a jogot, hogy akár Z80 néven később olyan processzort hozzon ki, ami ezekre a kódokra mást csinál. Vagy éppen ez volt a továbbfejlesztésre szánt slot, későbbi Z80-nal felülről kompatibilis processzorba ide rakták be az új utasításokat. Nos, ezek alapján helyes egy olyan kód, amelyik használ ilyen utasításokat is? Véleményem szerint: ha azt mondom, hogy arra a konkrét Z80 processzorra írtam, ami itt van a kezemben, akkor helyes, hiszen lásd, működik. Ha azt mondom, hogy Z80-ra írtam (úgy általában), akkor még ha ebben a pillanatban a világ összes Z80-asa is jól hajtja végre, akkor sem helyes, mert lehet hogy ami holnap jön ki a gyárból, az (bármiféle figyelmeztetés nélkül) már hülyeséget fog csinálni.
Igen ezzel többé kevésbé egyet lehet érteni. Hányszor futottam én is
hibás doksiba és szinte bitenként kellett kitrappelni mit csinál
a proci! Szóval nagyrészt művita ami itt folyik, kellő tapasztalat
birtokában ha nem is definiálható, de legalább érezhető milyen
a szép kód (szándékosan nem használom a "jó kód" kifejezést).
Az assemblyt ezért szerettem: ott a szép kód egyúttal jó is volt.
- A hozzászóláshoz be kell jelentkezni
Téhát akkor lerövidítve:
Van a common.h, ebben
//
extern int valami
//
aztán van egy másik fájl ami
//
#include common.hu
static int valami
//
És erre dob egy hátast FORDÍTÁSKOR?
- A hozzászóláshoz be kell jelentkezni
[quote:b9b9e0d0a0="meditor"]Téhát akkor lerövidítve: [...] És erre dob egy hátast FORDÍTÁSKOR?
Igen. Ez persze tovább is rövidíthető így:
extern int valami;
static int valami;
(persze a két "valami" az ugyanaz a változónév).
Fordításkor úgy dönt, hogy ő a valamiről nem tudja eldönteni, hogy statikus változó legyen-e vagy sem, hiszen a két deklaráció ellentmond egymásnak, és ezért dob egy hibát. Például a prboom fordítási naplójából idézve:
p_mobj.c:805: error: static declaration of 'itemrespawntime' follows non-static declaration
p_mobj.h:392: error: previous declaration of 'itemrespawntime' was here
- A hozzászóláshoz be kell jelentkezni
Na, akkor egy kis externológia saját praxis alapján:
Én az extern tárolási osztályt akkor használom, hogy egy adott
változóról a forditás során mindössze a típusát tudom, de
a címét nem. A memóriában elfoglalt helye akkor számolódik
ki, amikor az obj fájlokat összelinkelem. Ezen obj fájlok közül
az egyik és csak az egyik tartalmaz egy olyan memóriafoglalást,
amelynek típusa megfelel az "extern"-ben definiáltaknak.
Ha jól értem a ti esetetekben előfordulhat, hogy az extern
és a nem extern (memóriafoglaló) deklaráció egy objecten
belül van. Eddig jó? (-::
- A hozzászóláshoz be kell jelentkezni
Hi!
Az a szomoru, hogy itt a Veszpremi Egyetemen igy 'oktatjak' a C-t.
By(t)e
TBS::Antiemes
:(
nálunk (elte) meg pont a c++-tanár (gsd) az egyik legjobb az egyetemen, szerintem..
c-t ugyan nem igazán tanítanak, de legalább nem tanítják rosszul:)
itt egy jó megmagyarázás, hogy miért nem jók az ilyen a[i]=a[i++] -szerű dolgok: katt, bár már elég jól elmondták páran.
--
G.
- A hozzászóláshoz be kell jelentkezni
[quote:1afd294de3="meditor"]Kedves Zahy!
szerintem ez a két dolog nem egyenlő C alatt:
int a = a; illetve int a = 'a';
Termeszetesen. Azert volt ott a szep nagy smiley ;-)
- A hozzászóláshoz be kell jelentkezni
[quote:9889fc5541="meditor"]Ha jól értem a ti esetetekben előfordulhat, hogy az extern
és a nem extern (memóriafoglaló) deklaráció egy objecten
belül van. Eddig jó? (-::
Ha jol veszem ki, a problema az extern es a static kozott van.
- A hozzászóláshoz be kell jelentkezni
[quote:7442da5af6="Zahy"][quote:7442da5af6="meditor"]Kedves Zahy!
szerintem ez a két dolog nem egyenlő C alatt:
int a = a; illetve int a = 'a';
Termeszetesen. Azert volt ott a szep nagy smiley ;-)
Bocsi (-:: úgy látszik nem volt elég nagy.
- A hozzászóláshoz be kell jelentkezni
[quote:13a157c294="meditor"][quote:13a157c294="1aca"][quote:13a157c294="meditor"]Ha a programot átalakítom így:
for( i=0;i<4; ) {t3[i]=t1[i];i++; t1[i]=t2[i];i--; t2[i]=t3[i];i++;}
mely kód ELMÉLETILEG equivalens az eredetivel (postinkremens index),
Hoppa! Epp az a baj, hogy nem ekvivalens, meg elmeletileg sem... Amint azt mar tobben is leirtak, egy ilyen kifejezes, mint
[code:1:13a157c294]t3[i] = t1[i++][/code:1:13a157c294]
nem ekvivalens azzal, hogy
[code:1:13a157c294]t3[i] = t1[i]; i++;[/code:1:13a157c294]
mert fugg a kiertekeles sorrendjetol: a jobb vagy baloldal ertekelodik ki hamarab.... Huha ez a sok jobb-baloldalazas mar mindjart politikai hangszint ad az egesznek :D
Jaja, nem ekvivalens, közben rájöttem, illetve VAN olyan
fordítóértelmezés, amelyben ekvivalens. Inkább azt akartam
írni, hogy a feladat megfogalmazója arra gondolhatott, amit
az én újraértelmezett kódom is tartalmaz, hacsak nem direkt
szívatta a diákokat. Azaz vagy butaság volt ezt a feladatot
kiadni, vagy gonoszság. Lehet választani.
Esetleg az ,hogy tanulságos legyen és az életben elkerűljenek egy csapdát és sok órai munkaidejűk ne veszen kárba egy apró kis hibától.
- A hozzászóláshoz be kell jelentkezni
[quote:57d42aa1e4="Zahy"][quote:57d42aa1e4="meditor"]Ha jól értem a ti esetetekben előfordulhat, hogy az extern
és a nem extern (memóriafoglaló) deklaráció egy objecten
belül van. Eddig jó? (-::
Ha jol veszem ki, a problema az extern es a static kozott van.
Nem kizárólag... Bár nem tiltott, de mégiscsak pongyola,
hogy egy fordítási objectumon belül van az extern és
a memóriafoglaló deklaráció... Ha már a szép kódról
csevegünk. Ilyenkor szerintem a feltételes fordítás lenne a
megoldás.
Egyébként én úgy értelmeztem hogy nem a static és az
extern a probléma, hanem az, hogy az adott változó
két különböző módon van deklarálva. Egyébként ez megengedett:
//
extern static valami
//
Amúgy, ha két különböző modulban is memóriát foglalsz egy változónak,
akkor linkeléskor sivalkodás van, akkor is, ha a két változó típusa és
tárolási osztálya megegyezik és azonos az extern típusával. A linker
egyszerűen nem tudja eldönteni melyiket használja, teljesen jogos
a reklamáció.
- A hozzászóláshoz be kell jelentkezni
Helló. Lenne itt egy probléma, amit még tanult kollegám, Antiemes sem ért.
Szóval a kód a következő:
[code:1:6508966ce4]#include <stdio.h>
int main(){
int t1[5]={1,2,3,4,0}, t2[5]={5,6,7,8,0}, t3[5]={0,0,0,0,0},i;
for (i=0;i<4;){
t3[i]=t1[i++];
t1[i]=t2[i--];
t2[i]=t3[i++];
}
for(i=0;i<4;i++)printf("%d ",t1[i]);
printf("\n");
for(i=0;i<4;i++)printf("%d ",t2[i]);
printf("\n");
for(i=0;i<4;i++)printf("%d ",t3[i]);
printf("\n");
return 0;
}[/code:1:6508966ce4]
Aztán:
[code:1:6508966ce4][kmarc] [$] gcc -o marklar marklar.c && ./marklar
1 6 7 8
1 6 7 8
1 6 7 8[/code:1:6508966ce4]
Majd:
[code:1:6508966ce4][kmarc] [$] gcc -O2 -o marklar marklar.c && ./marklar
6 7 8 0
5 0 1 2
0 1 2 3[/code:1:6508966ce4]
Állítólag Windows alatt valamilyen módon lefordítva ez a kód a t1[] és t2[] tömb elemeit cseréli fel. Várjuk az ötleteket, előre is kössz :-)
gcc-3.3.6. Ja, és persze Slackware linux. Antiemes szerint lehet, hogy ez a baj...
- A hozzászóláshoz be kell jelentkezni
Az extern jelen esetben szerintem tök lényegtelen. Az a gond, hogy egyszer static, egyszer meg nem static.
- A hozzászóláshoz be kell jelentkezni
[quote:e9c80411f6="nosy"]kmARC:
akkor most aggodhatok hogy a fiamnak mplayer-rel lejatszott micimacko
video egyszercsak pornoba valt (bar nem tudom melyik a jobb) ? :)
udv, ncs
Azt nem tudni mindenesetre látam a: Hókefélke és a 7 törpe című müvet. :) Lehet így jöt létre.
Egyébként az egyik könyvben is van egyehez hasonló példa. Mindjárt az elején és ot is ilyen számolásos dologal szemléltetik a külömbséget a fordítók közöt.
- A hozzászóláshoz be kell jelentkezni
Újabb fordítóval ez a hiba nem volt előidézhető:
[code:1:70da48ec72]csko@ubuntu:~/prog$ gcc -o marklar marklar.c && ./marklar
1 6 7 8
1 6 7 8
1 6 7 8
csko@ubuntu:~/prog$ gcc -O2 -o marklar marklar.c && ./marklar
1 6 7 8
1 6 7 8
1 6 7 8
[/code:1:70da48ec72]
A rendszer:
[code:1:70da48ec72]Linux ubuntu 2.6.12-9-386 #1 Mon Oct 10 13:14:36 BST 2005 i686 GNU/Linux
Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v --enable-languages=c,c++,java,f95,objc,ada,treelang --prefix=/usr --with-gxx-include-dir=/usr/include/c++/4.0.2 --enable-shared --with-system-zlib --libexecdir=/usr/lib --enable-nls --without-included-gettext --enable-threads=posix --program-suffix=-4.0 --enable-__cxa_atexit --enable-libstdcxx-allocator=mt --enable-clocale=gnu --enable-libstdcxx-debug --enable-java-gc=boehm --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-4.0-1.4.2.0/jre --enable-mpfr --disable-werror --enable-checking=release i486-linux-gnu
Thread model: posix
gcc version 4.0.2 20050808 (prerelease) (Ubuntu 4.0.1-4ubuntu9)
[/code:1:70da48ec72]
Viszont gcc 3.3.5-tel pontosan azt a hibát észleltem amit te.
- A hozzászóláshoz be kell jelentkezni
[quote:a9b7301305="egmont"]Az extern jelen esetben szerintem tök lényegtelen. Az a gond, hogy egyszer static, egyszer meg nem static.
Szerintem az önmagámban probléma, ha egy változót kétszer
definiálsz egy több obj-os programban, függetlenül a statictól.
Igaz a probléma csak a linkelésnél - tehát később - jön elő.
- A hozzászóláshoz be kell jelentkezni
Na. Debian-user Antiemes szerint is azért van ez így, mert a rendszer Slackware 10.2 (Bár szerinte a KDE miatt van a hiba :-D)
Esetleg ha mások is kipróbálnák...
gcc-3.3.6 amúgy.
Csak most ettem észre az utolsó mondatod:
[quote:124fcaa4ed="csko"]Viszont gcc 3.3.5-tel pontosan azt a hibát észleltem amit te.
Mi is a gcc-verziók különbségében gyanítjuk a hibát.
Mindenesetre érdekes, egy ilyen kis semmiség kód...
- A hozzászóláshoz be kell jelentkezni
hi,
bar nem vagyok informatikus, de c-ben egy
foo[i]=bar[i++] jellegu kifejezesre
"undefined, unspecified" vagy
"implementation specific" jelzot szoktak
hasznalni az okosok. lehet vitazni hogy melyik (meg hogy
melyik mit is jelent). mindenesetre szamomra
ez azt jelenti hogy ne hasznaljuk a szerkezetet.
a hsznalata soran bekovetkezo furcsa dolgokat
megerteni meg a fordito forraskodja alapjan lehetne (talan).
udv, ncs
- A hozzászóláshoz be kell jelentkezni
//
extern static valami
//
hmm... most ezt komolyan gondoltad? hogy lehet valami egyszerre extern es static is? probald ki, mit szol hozza a gcc :D
extern azt jelenti "nem ebben a modulban van", static azt jelenti "ebben a modulban van, de kivulrol nem latszik" (a staticnak mas jelentese van lokalis valtozoknal).
- A hozzászóláshoz be kell jelentkezni
Kiprobaltam nem gcc-vel forditva. Az MS C/C++ forditojanak 13.10.3077 verziojaval (Visual Studio .NET 2003) nem jott elo egyik altalam hasznalt optimalizacios kapcsoloval sem, mig az Intel C++ compiler 9.0.019 eseteben tapasztalhato a jelenseg:
[code:1:dceb07a65e]
C:\2>icl marklar.c
Intel(R) C++ Compiler for 32-bit applications, Version 9.0 Build 20050430Z P
ckage ID: W_CC_P_9.0.019
Copyright (C) 1985-2005 Intel Corporation. All rights reserved.
marklar.c
Microsoft (R) Incremental Linker Version 7.10.3077
Copyright (C) Microsoft Corporation. All rights reserved.
-out:marklar.exe
marklar.obj
C:\2>marklar.exe
6 7 8 0
5 0 1 2
0 1 2 3
[/code:1:dceb07a65e]
- A hozzászóláshoz be kell jelentkezni
Hi!
[code:1:b631e32c07]
Reading specs from /woody/usr/bin/../lib/gcc-lib/i486-linux/3.3.5/specs
Configured with: ../src/configure -v --enable-languages=c,c++,java,f77,pascal,objc,ada,treelang --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-gxx-include-dir=/usr/include/c++/3.3 --enable-shared --with-system-zlib --enable-nls --without-included-gettext --enable-__cxa_atexit --enable-clocale=gnu --enable-debug --enable-java-gc=boehm --enable-java-awt=xlib --enable-objc-gc i486-linux
Thread model: posix
gcc version 3.3.5 (Debian 1:3.3.5-2)
[/code:1:b631e32c07]
A hiba itt is fennall. (Debian Woody)
[code:1:b631e32c07]
Reading specs from /usr/lib/gcc-lib/i486-linux/3.3.6/specs
Configured with: ../src/configure -v --enable-languages=c,c++,java,f77,pascal,objc,ada,treelang --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-gxx-include-dir=/usr/include/c++/3.3 --enable-shared --enable-__cxa_atexit --with-system-zlib --enable-nls --without-included-gettext --enable-clocale=gnu --enable-debug --enable-java-gc=boehm --enable-java-awt=xlib --enable-objc-gc i486-linux
Thread model: posix
gcc version 3.3.6 (Debian 1:3.3.6-6)
[/code:1:b631e32c07]
A hiba itt is fennall, pedig 3.3.6-os a gcc. (Debian Sarge)
A jooreg 2.95.2 viszont tokeletes: (Debian Potato)
[code:1:b631e32c07]
Reading specs from /usr/lib/gcc-lib/i386-linux/2.95.2/specs
gcc version 2.95.2 20000220 (Debian GNU/Linux)
[/code:1:b631e32c07]
By(t)e
TBS::Antiemes
- A hozzászóláshoz be kell jelentkezni
ha -Wall -al forditod, akkor sikoltozik is:
test2.c:7: warning: operation on 'i' may be undefined
test2.c:8: warning: operation on 'i' may be undefined
test2.c:9: warning: operation on 'i' may be undefined
es a hiba nem all fenn ezzel:
Target: i486-linux-gnu
Configured with: ../src/configure -v --enable-languages=c,c++,java,f95,objc,ada,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --program-suffix=-4.0 --enable-__cxa_atexit --enable-libstdcxx-allocator=mt --enable-clocale=gnu --enable-libstdcxx-debug --enable-java-gc=boehm --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-4.0-1.4.2.0/jre --enable-mpfr --disable-werror --enable-checking=release i486-linux-gnu
Thread model: posix
gcc version 4.0.2 (Debian 4.0.2-2)
- A hozzászóláshoz be kell jelentkezni
FreeBSD 6 alatt sux lett (gcc 3.4.4) :-) At kene allnom debianra, ott biztos jol megy :->>
- A hozzászóláshoz be kell jelentkezni
hali
ventura@dell:/tmp$ gcc-3.3 -o marklar marklar.c && ./marklar
1 6 7 8
1 6 7 8
1 6 7 8
ventura@dell:/tmp$ gcc-3.3 -O2 -o marklar marklar.c && ./marklar
6 7 8 0
5 0 1 2
0 1 2 3
ventura@dell:/tmp$ gcc-4.0 -o marklar marklar.c && ./marklar
1 6 7 8
1 6 7 8
1 6 7 8
ventura@dell:/tmp$ gcc-4.0 -O2 -o marklar marklar.c && ./marklar
1 6 7 8
1 6 7 8
1 6 7 8
ventura@dell:/tmp$
ezek 3.3.6 os gcc es 4.0.3
ez pedig aix 3.0.1 :>
bogik@delfin:/tmp$gcc -o marklar marklar.c && ./marklar 1 6 7 8
1 6 7 8
1 6 7 8
1 6 7 8
bogik@delfin:/tmp$ gcc -O2 -o marklar marklar.c && ./marklar
1 6 7 8
1 6 7 8
1 6 7 8
- A hozzászóláshoz be kell jelentkezni
[quote:f8d39c5eff="nosy"]hi,
bar nem vagyok informatikus, de c-ben egy
foo[i]=bar[i++] jellegu kifejezesre
"undefined, unspecified" vagy
"implementation specific" jelzot szoktak
hasznalni az okosok. lehet vitazni hogy melyik (meg hogy
melyik mit is jelent). mindenesetre szamomra
ez azt jelenti hogy ne hasznaljuk a szerkezetet.
a hsznalata soran bekovetkezo furcsa dolgokat
megerteni meg a fordito forraskodja alapjan lehetne (talan).
udv, ncs
Ommm.. szerintem meg eleg elterjedt dolog a tomb[i++], stb. hasznalata, lasd pl.: mplayer, vagy akarmi forraskod. Kicsit rovidebbe, egyszerubbe teszi a progit. Minek tegyunk meg egy sort inkrementalasnak, ha azt az elozobn is el tudunk vegezni.
Kosz, hogy ennyien utananeztetek. Ezek szerint:
i) 3.3-as szeriaval mas a ketfajta forditas
ii) 3.4-essel nem mas
iii) 4.0-ssal sem mas
iv) windows alatt sem csereli meg a t1 es t2 tomb elemeit...:-) (egyetemi zh-feladat... ;-) )
- A hozzászóláshoz be kell jelentkezni
[quote:ef45a78e16="8192Joco"][quote:ef45a78e16="meditor"]
...
Azaz vagy butaság volt ezt a feladatot
kiadni, vagy gonoszság. Lehet választani.
Esetleg az ,hogy tanulságos legyen és az életben elkerűljenek egy csapdát és sok órai munkaidejűk ne veszen kárba egy apró kis hibától.
A leirtak alapjan ez ketlem... Esetleg ha tudnank a lehetseges valaszokat (ha teszt volt), akkor el lehetne donteni.
Az "apro kis hiba"-rol meg csak annyit, hogy ahany C/C++ konyvet, online doksit olvastam eddig, a prefix es postfix increment/decrement operatoroknal mindig ott volt, hogy az ilyesmit keruljuk, mert nincs meghatarozva a szabvanyban. Szvsz ez nem apro kis tevedes, hanem szarvashiba.
- A hozzászóláshoz be kell jelentkezni
A megoldas:
volatile int i;
- A hozzászóláshoz be kell jelentkezni
[quote:aacb6b3640="kmARC"]Ommm.. szerintem meg eleg elterjedt dolog a tomb[i++]
de nem az egy lepesben torteno modositasa es cimzesre valo hasznalata
[quote:aacb6b3640="kmARC"]Minek tegyunk meg egy sort inkrementalasnak, ha azt az elozobn is el tudunk vegezni.
K&R urak irtak: "The moral is that writing code that depends on order of evaluation is a bad programming practice in any language"
- A hozzászóláshoz be kell jelentkezni
Hi!
[quote:5e48767b68="LeslieT"]A megoldas:
volatile int i;
Ez mit jelent?
By(t)e
TBS::Antiemes
- A hozzászóláshoz be kell jelentkezni
Egyebkent mukodesileg azert nem ajanlott ezt a format hasznalni, mert nincs ra garancia hogy a tx[i] cimet hamarabb kiertekeli a program, megmielott megnoveli az i erteket.
- A hozzászóláshoz be kell jelentkezni
Elég jól felhivta rá a figyelmet ,hogy kerűljétek. Most is it azon megy az agyalás, hogy az igy csapnivaló dolog. Apró kis hibának azért írtam mert nehzen veszed észre ha fut a programod. Esetleg az űgyfél rendeli töled határdőre egy másik architekturára vagy distribucióra vagy operáciosrendszere és ot nem a kivánt eredményel fordítja le a programodat a complier te meg esetleg a rohanásban csak bedobod egy CD-n a táskádba azt az ügyfélnél nem sikerűl a prezetáció a dologról vagy viszamész egy rejtet bug miat 100 szor. Most szívj vele az egyetemen egy kicsit mert így könyeben megjegyzed mint amikor az életben esetleg egy jó állástól vagy más számodra fontos dologtól esel ell. Az Egmont az UHU csomagolópartin direkt feladot olyan feladatot ami az adig tanitotak alapján nem működöt. Ezt azért tete mert így joban rögzült a dolog a halgatóknak.
Na tehát Gonosz, nem ért hozzá, vagy gyakorlot pedagogus aki a diákot a saját érdekében akár meg is szívatja ,hogy megjegyezen dolgokat?
- A hozzászóláshoz be kell jelentkezni
[quote:d8cb0d915f="snq-"][quote:d8cb0d915f="kmARC"]Ommm.. szerintem meg eleg elterjedt dolog a tomb[i++]
de nem az egy lepesben torteno modositasa es cimzesre valo hasznalata
Mondasz valamit...
[quote:d8cb0d915f="snq-"][quote:d8cb0d915f="kmARC"]Minek tegyunk meg egy sort inkrementalasnak, ha azt az elozobn is el tudunk vegezni.
K&R urak irtak: "The moral is that writing code that depends on order of evaluation is a bad programming practice in any language"
Ha ez vicc, akkor jo poen :-) vagy tenyleg ezt mondtak volna? :roll:
- A hozzászóláshoz be kell jelentkezni
[quote:9e264622e8="antiemes"]Hi!
[quote:9e264622e8="LeslieT"]A megoldas:
volatile int i;
Ez mit jelent?
A volatile tipusminosito azt jelzi, hogy a fordito nem tud mindent ami a valtozoval tortenhet. Ezert mindig a memoriabol (nem a regiszterekbol) veszi ennek az erteket. Itt azert segit, mert igy az i-vel torteno muvelet eseten tkeppen nem optimalizal a fordito (problema megkerulese).
- A hozzászóláshoz be kell jelentkezni
[quote:0e86b7f6f2="8192Joco"]Elég jól felhivta rá a figyelmet ,hogy kerűljétek. Most is it azon megy az agyalás, hogy az igy csapnivaló dolog. Apró kis hibának azért írtam mert nehzen veszed észre ha fut a programod. Esetleg az űgyfél rendeli töled határdőre egy másik architekturára vagy distribucióra vagy operáciosrendszere és ot nem a kivánt eredményel fordítja le a programodat a complier te meg esetleg a rohanásban csak bedobod egy CD-n a táskádba azt az ügyfélnél nem sikerűl a prezetáció a dologról vagy viszamész egy rejtet bug miat 100 szor. Most szívj vele az egyetemen egy kicsit mert így könyeben megjegyzed mint amikor az életben esetleg egy jó állástól vagy más számodra fontos dologtól esel ell. Az Egmont az UHU csomagolópartin direkt feladot olyan feladatot ami az adig tanitotak alapján nem működöt. Ezt azért tete mert így joban rögzült a dolog a halgatóknak.
Na tehát Gonosz, nem ért hozzá, vagy gyakorlot pedagogus aki a diákot a saját érdekében akár meg is szívatja ,hogy megjegyezen dolgokat?
A helyzet az, hogy a tanar szerint a program fel kene cserelje ket tomb elemeit. Hmmm. Namarmost ez mi szerinted?
Ja es a kettos betukre felhivnam a figyelmed, eleg szar olvasni a fenti szoveget pl. ;)
- A hozzászóláshoz be kell jelentkezni
Ez a programkód több szempontból is szemet sértő...
- teljesen fölösleges a ciklusba az i++, i--, i++ - bőven elég egyszer az i++ - amit egyébként jobb érzésű programozó a for ciklusba rak. Tehát
for( i = 0; i < 4; i++)
{
t3[ i ] = t1[ i ];
t1[ i ] = t2[ i ]];
t2[ i ] = t3[ i ];
}
- a tömb elemeinek cserélgetéséhez teljesen fölösleges egy újabb tömböt felvenni, azaz a teljes t3[] helyett elég mondjuk egy j változó és t3[ i ] helyére mindenhol j-t írni. Abba most nem mennék bele, hogy két érték hogy cserélhető fel segésdváltozó használata nélkül...
- a kód egyértelműen kétértelmű, mert egy t3[ i ] = t1[ i++ ] kétféleképpen is értelmezhető attól függően, hogy elöbb a jobb oldalt értékelem-e ki és csak utána határozom meg, hogy ezt melyik tömb elembe kell tenni, vagy elöbb kikeresem az adott tömb elem címét, ezt megjegyzem, majd _utána_ hajtom végre a jobb oldali kifejezést. Mivel a jobb oldali kifejezés kiértékelése megváltoztatja a baloldallon használt index értékét, ezért a sorrend nagyon nem mindegy - ám nem tudok olyan ajánlásról, ami a sorrendet meghatározná. Illetve egyről tudok: a program legyen olyan, hogy sorrend függetlenül ugyanazt csinálja, ám ez esetünkben nem teljesül.
Szóval maradjunk annyiban, hogy ez egy nagyon csúnya kód...
Ja és még egy megjegyzés: esetünkben _nem_ segít a volatile előírás sem. A volatile arra használt, hogy az adott változó minden esetben kerüljön betöltésre a memóriából, ne történjen regiszter optimalizálás. Csakhogy esetünkben nem a regiszter optimalizálással van a probléma, hanem a végrehajtási sorrenddel - és ezen a volatile nem segít.
Hogy egy példát mondjak a volatile használatára.
volatile int must_exit;
...
must_exit = 0;
while( must_exit == 0 )
{
}
Mivel a fordító konstatálja, hogy a must_exit értéke 0 és ezt a belső ciklus sosem változtatja meg, ezért a teljes feltétel fordítási időben is kiértékelhető és mint ilyen, mindíg igaz lesz. Ez ugyan egy kiváló optimalizáció és a fölösleges vizsgálat elhagyása a program futását is gyorsítja - ám ha mondjuk a SIGTERM kezelését átvesszük és ebben az interrupt-ban állítjuk át a must_exit értékét 1-re, akkor bár a fordítónak igaza lesz abban, hogy cikluson belül sehol sem kap értéket a változó, de ettől még a végkonklúzióban tévedni fog. Ezért elő _kell_ írni, hogy a változó volatile, azaz ne optimalizálja - így a SIGTERM hatására futó sighandler függvény ha megváltoztatja a változó értékét, akkor a ciklus ki fog lépni.
De mint hangsúlyozom, ez csak az optimalizálást szünteti meg - a kiértékelési _sorrendet_ nem. Innen kezdve az alapprobléma továbbra is áll: vajh a fordító milyen kódot generál? Elöbb az eredmény és utána a hová is teszem - vagy fordítva?
- A hozzászóláshoz be kell jelentkezni
Jocónak abban igaza van, hogy a tanár feladata minden helyzetre
felkészíteni a diákot. Az az érzésem ebben az esetben aki nem volt
felkészülve minden eshetőségre, az a tanár volt, de nem ismerem
a szitut, úgyhogy nem törnék pálcát fölötte.
- A hozzászóláshoz be kell jelentkezni
[quote:664986a00b="Zs"]Szóval maradjunk annyiban, hogy ez egy nagyon csúnya kód...
Mint említettem, ez egy ZH-feladat. Egy elborult tanár találta ki. Mivel a válaszok közül, amik a tesztben le voltak íra, egy sem volt jó, beírtam, lefordítottam, hülyeség jött ki. Poénból -O2-el lefordítottam, más hülyeség jött ki.
Amúgy az én véleményem szerint is fölösleges, jobban megvalósítható kód a fenti.
- A hozzászóláshoz be kell jelentkezni
kmARC:
"Ommm.. szerintem meg eleg elterjedt dolog a tomb[i++], stb. hasznalata, lasd pl.: mplayer, vagy akarmi forraskod. ..."
akkor most aggodhatok hogy a fiamnak mplayer-rel lejatszott micimacko
video egyszercsak pornoba valt (bar nem tudom melyik a jobb) ? :)
Zs:
az eredeti kod egyszerunek es optimalizaltnak probal meg latszani.
engem inkabb az erdekelne hogy ki az aki nem mutatokat hasznal ilyan
jellegu cserelgetes eseten....
udv, ncs
- A hozzászóláshoz be kell jelentkezni
[quote:22bcf9ebb7="nosy"]akkor most aggodhatok hogy a fiamnak mplayer-rel lejatszott micimacko video egyszercsak pornoba valt (bar nem tudom melyik a jobb) ? :)
lol
Akkor arra a kódra sok amunkahelyénzugpornónézőabberált ember lenne kíváncsi :-D :-D :-D
[OFF]
Amúgy senkinek nem jelent semmit az a fájlnév, hogy marklar?
[/OFF]
- A hozzászóláshoz be kell jelentkezni
:-)
Úgy látom jól eldiskurálgattok, kár, hogy már számomra érthetetlen dolgokról... ;-)
Amúgy végülis a ZH-n a bejelölendő álasz a két tömb elemeinek felcserélése volt, de a ZH-t felügyelő tanár "beismerte", hogy valahol valaki hibázott a kódot illetően.
- A hozzászóláshoz be kell jelentkezni
Hi!
De nekem igen! :D
Amugy azt az 'embert' ismerem, aki ezt a kodot kitalalta, es nemkicsit idiota.
Most akartam irni rola par dolgot, de mivel nemi kozom van ahhoz a tanszekhez, ahol o dolgozik, es mint tudjuk, a falnak is fule van (vagy inkabb meg a proxy is logol, hogy stilusos legyek :D), nem arulok el rola semmit.
By(t)e
TBS::Antiemes
- A hozzászóláshoz be kell jelentkezni
[quote:52c48afd56="micsa"]
//
extern static valami
//
hmm... most ezt komolyan gondoltad? hogy lehet valami egyszerre extern es static is? probald ki, mit szol hozza a gcc :D
extern azt jelenti "nem ebben a modulban van", static azt jelenti "ebben a modulban van, de kivulrol nem latszik" (a staticnak mas jelentese van lokalis valtozoknal).
A gcc simán megeszi. A staticnak valóban más a jelentése a globális
és a lokális változóknál. A lokális változó esetében a változó
nem lapozódik ki a memóriából, globális változó esetén pedig
a változó exportálási lehetőségét zárja ki. Ugyanakkor EGY modulon
belül nyugodtan lehet használni az extern static valami formulát,
hibát nem jelez, az persze más kérdés, hogy tök értelmetlen.
A static c++ - ban újabb jelentéssel bűvül, de ez már egy másik topik lenne. (-::
- A hozzászóláshoz be kell jelentkezni
kmARC:
"Amúgy senkinek nem jelent semmit az a fájlnév, hogy marklar? "
dehogynem! teljesen veletlenul a temaindito kodot egy marklar.c
fileba masoltam bele. termeszetesen az eddig emlitett egyetlen furcsasag
sem jott elo vele kapcsolatban amikor kiprobaltam az egyik 286-os
pecemen levo macosx alatti intel forditoval. :)
udv, ncs
- A hozzászóláshoz be kell jelentkezni
Hi!
Ez egy bolcs es igaz marklar volt? :D
Bovebben a Marklarrol:
http://en.wikipedia.org/wiki/Marklar
By(t)e
TBS::Antiemes
- A hozzászóláshoz be kell jelentkezni