* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Nejcastejsi chybove hlasky Pascalu, co znamenaji a jak se jich zbavit * * ======================================================================= * * sepsal Mircosoft (http://mircosoft.mzf.cz) * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Psano v prostredi Turbo Pascalu, doporucuji otevrit tamtez. Obsah: 1 - Chyby pri prekladu 2 - Chyby vznikle za behu programu Cisla u jednotlivych hlasek odpovidaji skutecnym cislum chyb, jak jsou hlaseny programem a jak je najdete v napovede. Napovedu k chybovym hlaskam ziskate napr. pouzitim Ctrl+F1 na slovo ERROR nebo primo z obsahu (Help -> Contents -> Error messages). Tady se pokusim vysvetlit ty, ktere se objevuji nejcasteji, a naznacit zpusob, jak je vyresit. ****************************************************************************** 1 - Chyby pri prekladu ****************************************************************************** Objevuji se pri pokusu zkompilovat napsany program, pokud obsahuje nejakou syntaktickou chybu, a proto zkompilovat nejde (urcite se tedy nespusti). Nahore se objevi cervena lista s chybovou hlaskou a kurzor bude umisten prave na teto chybe. Po stisku F1 se zobrazi napoveda k teto hlasce (to plati pro vsechny chyby, pri kterych uvidite cervenou listu). 1 Out of memory ================ Znamena "nedostatek pameti pro preklad". Rychle reseni: jestli jste az doted pouzivali prostredi TURBO.EXE, prejdete na TPX.EXE. To dokaze prekladac nacpat nekam do rozsirene pameti, takze hned bude vic mista. Jestli uz v TPX jste, zkousejte postupne polozky z nasledujiciho seznamu: Options -> Linker: Link buffer nastavte na Disk, Map file na Off. Compile: Destination nastavte na Disk. Zavrete vsechny otevrene soubory, ktere zrovna nepotrebujete. Options -> Compiler: vypnete vse v ramecku Debugging a Runtime errors. Zkuste projit vsechny jednotky, ktere vas program pouziva, a kazdou zvlast prelozit volbou Compile -> Build. Pokud jste v DOSu, ukoncete vsechny rezidentni programy, ktere nepotrebujete. Ve Windows je pamet spravovana trochu jinak, takze toto nepomuze. Jestli se chyba i po tom vsem stale jeste objevuje, budete muset prekopat svuj program: textove a jine objemne konstanty presunout do externich datovych souboru, zrusit pouzivani ruznych velkych jednotek, ze kterych potrebujete treba jen jednu kratkou proceduru, pouzit prekryvani jednotek (neumim, nevysvetlim) atd.. Kdyz selze i to, vypnete vyvojove prostredi a program prelozte prekladacem TPC.EXE z prikazoveho radku. A jestli nepomuze ani to, tak uz opravdu nevim... 3 Unknown identifier ===================== Znamena "tenhle identifikator neznam". Reseni: podivejte se, kde je kurzor. Prectete si to slovo. Zkontrolujte, jestli v nem neni preklep. Jestli ne, tak zkontrolujte, jestli uz jste ho predtim nekde deklarovali - vsechno musi byt napred deklarovano, nez se to poprve pouzije, jinak prekladac nevi, o co jde. Pokud ano, podivejte se, KDE jste to deklarovali. Neni ta deklarace az za tim mistem, kde uz identifikator pouzivate? A neni treba lokalni? Z hlavniho programu se k lokalnim vecem nedostanete. Btw., tehle hlasky se da dobre vyuzit jako "zalozky". Pisu neco v pulce dlouheho zdrojaku, potrebuju se podivat nekam jinam a pak se sem zase rychle vratit. Na to staci napsat na prislusne misto nejakou blbost a kdykoli potom stisknete F9 (prelozit), kurzor se prave na teto blbosti zastavi - jednoduche a ucinne :-). "NECO" expected ================== Cili "tady jsem cekal to "NECO" a ne to, co je tu ted". NECO muzou byt ruzne symboly, klicova slova apod. Vyskyt (napr.): mam proceduru deklarovanou s jednim parametrem, ale v progra- mu se ji omylem pokusim zavolat se dvema parametry. Prekladac se zastavi na carce mezi paramatry a nahlasi: ")" expected. Tim rika, ze ta procedura uz zadne dalsi parametry mit nema, takze co tu dela ta carka, kdyz tam ma koncit zavorka? Nebo: napisu if a=b writeln('bla');. Vidite, ze jsem tam zapomnel napsat then. Takze preklad se zastavi na writeln a nahlasi se: "THEN" expected. Tak ho tam dopisu a je to vyreseno. Reseni: prectete si, CO ze tam cekal. Pak si prohlidnete okoli, PROC to tam cekal. Pak by to melo byt jasne. Muze se sice stat, ze prekladac nekde ocekava neco, co tam v zadnem pripade neocekavate vy, ale to je vase chyba, protoze jste nejspis o kus driv neco popletli tak, ze ho to uplne zmatlo. 4 Duplicate identifier: NECO (NECO je nejaky identifikator) ============================ Znamena "NECO je duplicitni, tj. to uz tu jednou bylo". Zkratka snazite se pojmenovat vic veci jednim jmenem nebo jste zapomneli, ze uz jste nejakou vec deklarovali a deklarujete ji podruhe. Reseni: najdete oba vyskyty prislusneho identifikatoru a rozhodnete se, co s nimi udelate, obvykle staci jeden prejmenovat. 5 Syntax error =============== Znamena "chyba syntaxe", coz zrovna moc nerekne. Prekladac ji hlasi, pokud najde ve zdrojovem kodu nejaky znak, ktery tam v tu chvili nema co delat, a nehodi se na to zadna jina chybova hlaska. 6 Error in real constant ========================= Cili "chyba v realne konstante". Nejspis jste to cislo spatne napsali :-). 7 Error in integer constant ============================ Aneb "chyba v celociselne konstante". Bud je zase chyba v zapisu cisla, nebo je napsane cislo vetsi nez povoleny rozsah longintu. Ovsem pozor. Tato hlaska se muze objevit i u takovych konstant (typu const jmeno=hodnota), ktere sice maji celociselnou hodnotu, ale vy osobne je povazujete za realne, takze by rozsah mel stacit. Jenze prekladac to nevi, a tak mysli, ze cislo, ve kterem neni zadna desetinna tecka, je cele a podle toho se k nemu chova. Takze pokud ma byt konstanta realna, pripiste k ni na konec desetinnou tecku a nulu. 8 String constant exceeds line =============================== Znamena "retezec presahuje konec radku". Nejspis jste nenapsali apostrof na konec retezce, tak ho tam ted napiste. Jestli potrebujete napsat retezec, ktery se nevejde na radek, spojte dva kratsi: 'prvni cast retezce '+ 'druha cast' 10 Unexpected end of file ========================== Tj. "neocekavany konec souboru". Objevuje se napr. kdyz zapomenete na koncove END. (s teckou) za koncem hlavni prikazove casti programu, nebo kdyz chcete nechat prelozit nejaky ukazkovy soubor, ktery obsahuje treba jednu proceduru a nic jineho. Proste aby se soubor prelozil, musi mit kompletni strukturu programu ((program) - begin - end.) nebo jednotky (unit - interface - - implementation - end.). Jina moznost je, ze jste do zdrojaku napsali nejaky specialni znak (mne se to jednou stalo s nejakou sipkou), ktery vyhrabete odnekud ze zacatku ASCII tabulky, a prekladac si ho vylozi jako kod "konec souboru". Takovy znak pak nahradte necim jinym, nejlepe s ordinalnim cislem >= 32. 11 Line too long ================= Znamena to "prilis dlouhy radek". Tuhle hlasku vylozene nesnasim. Maximalni delka radku je 127 znaku. Pokud bude delsi, pujde soubor sice normalne ulozit (F2 nebo File -> Save) a nic neztratite, ale nepujde prelozit. Prekladac asi nema na moc dlouhe radky pamet. Tato chyba se objevuje vzdy, kdyz je radek moc dlouhy, vubec nezalezi na tom, co na nem je, takze ji zpusobi i dlouhy komentar. Reseni: zkratit ten radek. Bud zmensenim odsazeni od leveho okraje nebo rozdelenim jeho obsahu do vic radku. 12 Type identifier expected ============================ Cili "tady jsem cekal identifikator typu a ne to, co tu je ted". Objevuje se hlavne v hlavickach procedur a funkci. Formalni parametry potrebu- ji udani typu jednim identifikatorem, ne nejakou slozitou konstrukci. Takze nemuzu napsat treba: procedure Neco(x:string[30]; y:^integer; z:record a,b:byte; end); ale musim nejdriv vsechny potrebne typy definovat: type str30=string[30]; ukinteger=^integer; zaznam=record a,b:byte end; a pak napsat: procedure Neco(x:str30; y:ukinteger; z:zaznam); Dalsi mozny vyskyt teto chyby: napisu "var x:" a ted zapomenu dopsat, jakeho typu ze ma x byt, a zacnu tam psat neco jineho. Reseni - dopsat ten typ. 13 Too many open files ======================= Znamena "prilis mnoho otevrenych souboru". Nejsem si jist, jestli tohle nahodou neni chyba pri behu programu a ne pri prekladu, ale mozna se objevuje v obou pripadech. Reseni: zkontrolujte soubor CONFIG.SYS. Kdyz tam uvidite radek FILES=neco, zmente "neco" na trochu vetsi cislo, to ale jen kdyz je "neco" treba 3; kdyz je 50, bude chyba jinde. Kdyz tam FILES neni, zkuste ho tam dopsat, treba FILES=50, ale myslim, ze vychozi hodnota je prave nejaka takova kolem 50. Zkuste program znovu. Jestli chyba nezmizela, dukladne se podivejte, kolik souboru jste v programu otvirali (Reset nebo Append) a jestli jste vsechny zase zavreli (Close). Nemate nekde otvirani nejakych souboru v nejakem nezvladnutem cyklu? 15 File not found (JMENO SOUBORU) ================================== Znamena to, ze receny soubor nebyl nalezen. Kurzor je na miste, kde jste se na tento soubor odkazovali. Obvykle se tato chyba objevuje za slovem Uses u nejake jednotky nebo na direktive {$I ...} pri primem vkladani souboru. Reseni: podivejte se, v jakem adresari se zrovna nachazite: File -> Change dir, ten aktualni je zvyrazneny zlute. Pak se podivejte do Options -> -> Directories na Unit directories a Include directories. Pak se podivejte, kde prislusne jednotky (PAS nebo TPU) nebo soubory pro vkladani mate. Pokud se jejich poloha shoduje s nastavenim Unit/Include directories, stal se zazrak, protoze v takovem pripade tato chyba vubec nemuze nastat. Spis tam ale bude nejaka jina cesta, tak ji prepiste na tu cestu, kde prislusnou jednotku skutecne mate. Pokud je cesta prazdna, bud ji stejnym zpusobem vyplnte, nebo se presunte s aktualnim adresarem (Change dir) do adresare s danou jednotkou nebo souborem (chce to enterem vybrat adresar a pak kliknout na OK, samotny enter nestaci). V Directories najdete jeste jednu volbu - EXE & TPU directory. Ta urcuje, kam prijdou zkompilovane programy (EXE) a jednotky (TPU). Pokud prekladac nenajde prislusnou jednotku v aktualnim adresari nebo v Unit directories, hleda ji tady - na to nekdy pozor. 17 Invalid compiler directive ============================== Znamena to "neplatna direktiva prekladace". O direktivach uz jsem jedno povidani napsal, takze jestli nevite, co to direktiva je, prectete si ho. Tato hlaska se objevi, pokud proste napisu spatnou direktivu: {$ a ted neco, co neni platna dirktiva}. 19 Undefined type in pointer definition (NECO) ===================================================== Cili "definovali jste nejaky typ ukazatele jako ukazatel na typ NECO, ale ten typ NECO uz jste definovat zapomneli". Ano, pri definici ukazatelu je mozne definovat ho jako ukazatel na neco, co zatim jeste definovano nebylo (drobna vyjimka z pravidel vytvorena specialne kvuli tomu, aby sly vytvaret dynamicke spojove seznamy). Ale to pak samozrejme nekde dodefinovat musime. Reseni: dodefinujte ten typ. Jestli uz definovany je, podivejte se, jestli v jeho identifikatoru neni preklep, nebo jestli neni definovany v jinem bloku nez ten ukazatel, ktery na nej proto nevidi. 20 Variable identifier expected ================================ Znamena "tady jsem ocekaval nejakou promennou a ne to, co je tu ted". Nejcasteji se vyskytuje, pokud mame proceduru s formalnim parametrem volanym odkazem (var) a snazime se ji v nem predat nejakou hodnotu. Klasicky pripad: Initgraph(9,2,'') nebo Blockwrite(f,'text',4). Reseni: vytvorte pomocnou promennou prislusneho typu, do ni vlozte pozadovanou hodnotu a tuto promennou pak predejte te procedure. 22 Structure too large ======================= Aneb "struktura je prilis velka". To jsem jednou zazil, kdyz jsem se snazil vytvorit pole nekolika obrazku jako pole dvojrozmernych poli :-) (jo, to byly casy...). Reseni: jestli taky chcete pole obrazku, udelejte je jako pole ukazatelu a pro kazdy ukazatel alokujte dynamickou promennou o prislusne velikosti. Tim se velka struktura rozlozi na vic mensich. Ukazatele jsou na takoveto veci vubec pomerne ucinnym a uzitecnym prostredkem. 23 Set base type out of range ============================== Znamena "typ prvku mnoziny je mimo povoleny rozsah". Mnozina se totiz muze skladat jen z prvku o velikosti 1B, tj. byte, shortint, char a ruzne intervaly v rozsazich techto typu. Takze integer apod. proste nejde. 24 File components may not be files or objects =============================================== Znamena to "soubory nebo objekty nemohou byt prvky souboru" a myslim, ze to nepotrebuje zadny dalsi komentar. Proste promenne typu file nebo object nemuzete primo zapisovat do souboru. Reseni: z tech souboru nebo objektu si prectete prislusna data a ta pak zapiste do toho souboru. 26 Type mismatch ================= Znamena "nesedi typ". Velmi casta hlaska :-). Rika, ze typ vyrazu, na kterem je zrovna kurzor, nema co delat na miste, kde tento vyraz zrovna je. Takze treba celociselnemu cislu prirazujeme realnou hodnotu (obracene to jde), procedure s var-parametrem jednoho typu predavame promennou jineho typu apod.. Casty vyskyt je u logickych vyrazu: if a>b and b,<,<>,>=,<=)! Z toho vyplyva, ze to prekladac pochopi takhle: if (a>(b and b))b) and (b1; Zkratka zalezi na tom, co zrovna presne potrebujete. 34 Invalid function result type ================================ Aneb "tenhle typ nejde pouzit jako navratova hodnota funkce". Jako navratovou hodnotu funkce muzeme pouzit vsechny ciselne typy (cele i realne), char, string a jakykoli ukazatel. Zaznamy, mnoziny, pole a podobne veci ne. 41 Operand types do not match operator ======================================= Znamena "typ operandu neodpovida operatoru" (operator je znamenko mezi dvema vyrazy, operandy jsou ty vyrazy; to jen tak pro upresneni :-) ). Vyskyt napr. pokud se pokousim delit realna cisla pomoci operatoru div nebo na ne pouzit bitove operace. Nebo neco podobneho, jako jsem popsal u chyby 26 "Type mismatch" (viz vyse) - kvuli popleteni priority operatoru se navzajem k sobe dostanou vyrazy takovych typu, jake k tem operatorum vubec nepatri. 42 Error in expression ======================= Cili "chyba ve vyrazu". Velmi obecna a spatne popsatelna chyba. Proste ten vyraz (vyrazem se mysli neco, co kdyz se spocita, da nejakou hodnotu, ze ano), na kterem je kurzor, je nejakym zpusobem spatne. V napovede rikaji, ze to muze byt tim, ze zapomenu napsat operator mezi dva operandy. Ano, to je jedna z mnoha moznosti... Takze jestli opravdu nevite, kde je chyba, zkuste treba pouzit vic zavorek nebo si predstavit, jak to asi prekladac precte. 44 Field identifier expected ============================= Tj. "tady jsem cekal identifikator nejake polozky zaznamu, objektu nebo pole". Treba jste zkouseli odkazat na neexistujici polozku zaznamu (zaznam.neco) nebo se pokousite priradit hodnotu celemu poli misto jedne jeho polozce. Dost spatne se to popisuje, ale az tuhle hlasku uvidite v konkretnim programu, urcite bude vsechno jasnejsi. 48 Code segment too large ========================== Znamena to "prilis velky Code segment". Code segment je ta cast programu, ve ktere jsou ulozeny vlastni prikazy a instrukce, konstanty s udanym typem (inicializovane promenne) a vsechna data, ktera prilinkujete direktivou {$L ...}, a jeho maximalni velikost je 64 KB. Jeste se mi nestalo, ze bych napsal neco tak velkeho, ze by Code segment nestacil, ale staci linknout nejaky ten BGI ovladac a k tomu par CHR fontu a je to. Kdyz tedy tuto hlasku uvidite, budete muset ozelet nadeji na jeden samostatny vse obsahujici exac a data ulozit do oddeleneho datoveho souboru. Jestli jste nic nelinkovali, ale opravdu jste napsali tak dlouhy program, rozhodte procedury z nej do jednotek. Kazda jednotka ma svuj vlastni code segment. 49 Data segment too large ========================== Cili "prilis velky Data segment". To je oblast, do ktere se ukladaji globalni promenne. Je jen jeden spolecny pro program i vsechny pouzite jednotky a jeho maximalni velikost je opet oblibenych 64 KB. Takze jestli vidite tuto hlasku, snazte se globalni promenne co nejvice nahradit lokalnimi (ty se tvori docasne na cca 16 KB velkem zasobniku) nebo dynamickymi (New, Getmem a spol., ktere bydli na hromade - 640 KB). 59 Undefined forward (NECO) ============================ Znamena "zapomneli jste definovat proceduru nebo funkci NECO, kterou jste nekde predem deklarovali". Deklaraci predem myslim (pro ucely tohoto textu) napsani hlavicky procedury nebo funkce (dale PF) s klicovym slovem Forward, deklaraci hlavicky PF v casti interface v jednotce a deklaraci hlavicky PF (metody) v definici objektu (typu object). K takhle avizovane hlavicce pak samozrejme musime nekde napsat cele telo dane PF. V pripade slova Forward kdekoli potom, v jednotce v casti implementation a u objektu kdekoli dale, kde to jde (tam pak nezapomente psat jmeno dane metody i se jmenem toho objektu!). Kdyz definici procedury prekladac nenajde, skonci na konci souboru s touto hlaskou. Pokud jste si jisti, ze jste danou PF urcite nekde psali, podivejte se dukladne, jestli neni treba ve jmenu preklep (nejjistejsi je celou hlavicku zkopirovat) nebo jestli neni v nejakem vnorenem bloku (treba lokalne v jine PF), kam neni od drive deklarovane hlavicky videt. 61 Invalid typecast ==================== Aneb "neplatne pretypovani". Promennou muzeme pretypovat jen na stejne velky typ (vyjimkou jsou jen celociselne typy, kde muzeme pretypovat treba integer na longint, ale treba na real uz ne). Takze treba real na array[1..6] of byte nebo record a,b,c,d:char end na pointer. Ale ne treba string[60] na array[1..10] of char, protoze to uz je jinak velke. Jestli si nejste jisti velikosti nejakeho typu nebo promenne, pouzijte Sizeof. Pokud nutne potrebuje- te pretypovat na ruzne velky typ, pouzijte ukazatel: ukazatel deklarovany jako ukazatel na cilovy typ nasmerujte na danou promennou (operatorem @ nebo Addr). Pak k ni pres tento ukazatel muzete pristupovat jako by se nechumelilo. Ale pozor na to, abyste nahodou neco nezapsali do pameti mimo tu promennou, z toho jsou Nepovolene Aplikace a podobne legracky. 62 Division by zero ==================== Cili proste "deleni nulou". Prekladac tuhle chybu muze najit jedine v nejakem konstantnim vyrazu a neni tezke ji odstranit. Jestli ji nevidite, prepocitejte si ten vyraz na kalkulacce a hned bude vsechno jasne. 63 Invalid file type ===================== Cili "neplatny typ souboru". Objevuje se napr. kdyz se pokousite zapisovat procedurou Writeln do jineho nez textoveho souboru (typ Text) apod. 64 Cannot read or write variables of this type =============================================== Znamena "nemuzu precist nebo zapsat promennou tohoto typu". Napr. pokud se pokousite zadat z klavesnice cely zaznam nebo pole. 68 Circular unit reference =========================== Znamena to "zacyklene pouzivani jednotek". Kdyz jedna jednotka pouziva druhou a ta druha zase tu prvni, chyba je tu. Ale jen pokud se takto pouzivaji v Uses v sekci Interface. V sekci Implementation to nevadi. Takze jestli potrebujete pouzivat jednotky navzajem, oznamte to az tam. 69 Unit name mismatch ====================== Tj. "nesedi jmeno jednotky". Jmeno jednotky uvedene v hlavicce (za slovem unit) se musi shodovat se jmenem souboru, do jakeho ji ukladate. 70 Unit version mismatch ========================= Znamena "nesedi verze jednotky". Objevuje se, pokud byly od posledni kompilace teto jednotky zmeneny jednotky, ktere pouziva. Odstrani se novym zkompilovanim (nejlepe Compile -> Build, coz natvrdo prekompiluje uplne vsechno). 76 Constant out of range ========================= Cili "konstanta je mimo povoleny rozsah hodnot". Objevuje se bud pokud se snazime pristupovat k prvku pole konstantnim indexem mimo rozsah pole (napr. var a:array[1..10] of...; a[100]:=...) nebo pokud prirazujeme nejake promenne nebo parametru procedury konstantni hodnotu mimo jeji rozsah (napr. var x:byte; x:=500). Na tohle se nevztahuje kontrola rozsahu ({$R+} nebo Options -> Compiler -> -> Range checking), rozsahy konstant kontroluje prekladac jeste pri prekladu. Reseni: dat jinou konstantu nebo zvetsit rozsah dane promenne nebo indexu pole. 97 Invalid FOR control variable ================================ Cili "neplatna ridici promenna for-cyklu". Ridici promenna musi byt deklarovana bud jako globalni, nebo jako lokalni v te procedure nebo funkci, ve ktere se pouziva (tj. ve stejnem bloku). Tato chyba se objevi v pripade, ze mame lokalne (tj. v jine procedure) definovanou proceduru a v ni for-cyklus, ktery chce pouzit jako ridici promennou nejakou promennou z te "nadrazene" procedury (tedy te, ve ktere je tato lokalni procedura vnorena). Reseni: deklarovat novou ridici promennou na spravnem miste. 112 CASE constant out of range =============================== Znamena "konstanta (u jedne z moznosti) v prikazu Case je mimo povoleny rozsah". Tento rozsah je -32768..65535 (tj. to nejmensi, co muzu dat do integeru, az to nejvetsi, co se vejde do wordu). Takze zadna longintova supervelka cisla. Reseni: opravdu potrebujete tak velke hodnoty? Mozna bude lepsi: misto: dat treba: case x of 0:... case x div 100 of 0:... 100:... 1:... 200:... 2:... end; end; 113 Error in statement ======================= Aneb "chyba v prikazu". Znamena to, ze ten symbol, na kterem se zastavil kurzor, je na takovem miste, jako kdyby to byl prikaz, ale je to nejaka kravina, ktera rozhodne prikaz netvori. Nejcastejsi vyskyt: kdyz v konstrukci "if podminka then prikaz1 else prikaz2;" napisete za prikaz1 strednik (pak bude kurzor na else). Nebo treba kdyz treba pisete repeat-cyklus, zapomenete napsat repeat a napisete jenom until. A tak dale. Obecne reseni: podivejte se, kde se kurzor zastavil a zkontrolujte, jestli syntaxe okolnich prikazu odpovida pravidlum (a kdyz uz tu ta chyba je, tak urcite odpovidat nebude). 116 Must be in 8087 mode to compile this ========================================= Tedy "abych tohle prelozil, musi byt zapnuty koprocesor (rezim 8087)". Pokud pisete v cistem Pascalu, objevi se tato hlaska ve chvili, kdy se snazite pouzit nektery z realnych typu single, double nebo extended nebo typ comp, a nemate pritom koprocesor zapnuty. V asm muzete primo pouzivat instrukce [ end ] koprocesoru (obvykle se poznaji podle toho, ze zacinaji na f), ale taktez musite nejdrive kopr zapnout. Takze reseni je jednoduche: zapnete ho :-). Bud direktivou {$N+} nebo zaskrtnutim policka Options -> Compiler -> 8087/80287. 121 Invalid qualifier ====================== To se preklada dost spatne ("neplatny kvalifikator"?). Jakmile zacnete pracovat s trochu slozitejsimi datovymi strukturami, budete tuto hlasku vidat pomerne casto :-). Objevuje se v techto pripadech: a) Pokousite se indexovat nejakou promennou, jako by to bylo pole, ale ono to pole neni. Priklad: Promenna[index]:=neco jde napsat, pokud Promenna je pole. Ale jestli je to treba integer, objevi se tahle hlaska. b) Pokousite se odkazat na polozku zaznamu, ale u nejake promenne, ktera neni zaznam. Napr.: Promenna.polozka:=neco. c) Pokousite se odkazat na neexistujici polozku zaznamu. d) Pokousite se odkazat na data, na ktera ukazuje nejaky ukazatel, jenze to neni ukazatel: Promenna^:=neco - kdyby Promenna byla ukazatel, vsechno by bylo OK. 122 Invalid variable reference =============================== Cili "nespravne pouziti promenne". Znamena to, ze jste napsali nejaky vyraz (promennou, funkci apod.) na misto, kde nema co delat (napr. jako prikaz). Tedy napr.: muzu napsat "x:=sin(y);" ale ne samostatne "sin(y);" jako prikaz. Obvykly vyskyt: chcete pockat na klavesu, tak napisete Readkey;. Jenze Readkey je funkce a ne procedura, a proto se neda jen tak napsat jako prikaz. Obvykle reseni: bud dane misto vyreste tak, aby se funkce opravdu volala jako funkce (napr. pomocna promenna typu char a napsat pom:=Readkey;) nebo zapnete rozsirenou syntaxi (Options -> Compiler -> Extended syntax nebo direktiva {$X+}), ktera takove volani funkci umoznuje (ale ne tech z jednotky System, u tech to musite vzdycky nejak obejit). 124 Statement part too large ============================= Znamena to "prilis dlouha prikazova cast". Maximalni delka souvisle prikazove casti (mezi begin a end) je cca 24 KB. Kdyby se vam nahodou povedlo toto cislo prekonat (pochybuji, ale mozne to teoreticky je), staci prikazy rozdelit do nekolika procedur - kazda muze mit svych vlastnich 24 kB. 126 Files must be var parameters ================================= Cili "promenna typu soubor jako parametr procedury nebo funkce musi byt vzdy volana odkazem". Pricina: napsali jste neco ve smyslu: procedure DelejNecoSeSouborem(soubor:file); Reseni: pripiste var: DelejNecoSeSouborem(VAR soubor:file); 131 Header does not match previous definition ============================================== Neboli "hlavicka neodpovida predchozi definici". Nekde drive jste predem deklarovali hlavicku teto procedury nebo funkce (v casti Interface v jednotce, pomoci slova Forward nebo jako metodu v definici objektu), ale ted, kdyz pisete cele telo procedury, vypada hlavicka jinak. Zrejme je tam o nejaky ten parametr vic nebo min nebo je tam preklep. Tak hlavicku opravte, aby se oba exemplare shodovaly. 133 Cannot evaluate this expression ==================================== Znamena "nemohu vyhodnotit (spocitat) tento vyraz". Vyskytne se napr. pokud se pokousite udelat pole s promennymi mezemi (var x:word; a:array[1..x]of...), coz nejde, nebo v definici konstanty pouzijete nejakou funkci (treba const konstanta=sin(10);) a podobne. Reseni: danou konstantu vypocitejte rucne a dopiste tam rovnou cislo. 140 Invalid floating point operation ===================================== Aneb "nepovolena operace s realnym cislem". Vznika pri podobnych prilezitos- tech jako chyba 207 za behu programu (viz dale), akorat ze na tuhle prijde uz prekladac, protoze vznikla pri pocitani konstantnich realnych vyrazu: deleni nulou, preteceni apod. 143 Invalid procedure or function reference ============================================ Cili "volate proceduru nebo funkci nespravnym zpusobem". Nejcastejsi pripad je, ze se pokousite volat proceduru jako vyraz (napr. x:=readln apod.). Nebo, pokud uz pouzivate takove vychytavky jako promenne typu procedura, tak ta procedura, na kterou smerujete nejakou proceduralni promennou, neni Far (definovana se slovem Far za hlavickou nebo s predem zapnutym dalekym volanim {$F+} nebo Options -> Compiler -> Force far calls) nebo je deklarovana jako inline nebo interrupt, coz v tomto pripade nejde. 148 Local object types are not allowed ======================================= Znamena "neni dovoleno definovat objekty lokalne". Objekty (typ object) proste musi byt definovany vzdy jen globalne. 155 Invalid combination of opcode and operands =============================================== Cili "spatna kombinace instrukce a operandu". Tato hlaska se objevuje, pokud v Asm kodu napisete u nejake instrukce napr. jiny pocet operandu nez ma byt (treba inc AX,3), pokusite se provest nejakou instrukci s takovymi operandy, s jakymi se provest neda (treba presun dat primo z promenne do promenne bez "mezistupen" pres registr) nebo nesedi velikost operandu (mov AX,BL apod.). [ end ] 159 286/287 instructions are not enabled ========================================= Znameny "neni povolena instrukcni sada pro procesor 286, ale presto tyto instrukce v programu pouzivate". Reseni je jednoduche: tu instrukcni sadu povolte. Bud Options -> Compiler -> 286 instructions nebo direktivou {$G+}. ****************************************************************************** 2 - Chyby vznikle za behu programu ****************************************************************************** Tech uz je o neco mene, ale o to jsou obvykle neprijemnejsi. Vznikaji, kdyz je program sice syntakticky spravne a jde spustit, ovsem za behu provede neco nepatricneho. Pokud program spoustite z IDE pres Ctrl+F9 (Run -> Run), objevi se po padu programu cervena lista s chybovou hlaskou a kurzor bude na miste, kde k chybe doslo. Pri spusteni programu jako hotoveho samostatneho EXE souboru uvidite na DOSove obrazovce sedivy text "Runtime error XXX at YYYY:ZZZZ.", coz znamena pouze "Doslo k chybe cislo XXX na adrese YYYY:ZZZZ.". Takze kouknete do napovedy na error messages a podle toho cisla najdete, co to bylo za chybu. Vsechny hlasky na tema File, Disk, Directory apod. =================================================== Tyto chyby se objevuji, pokud mate zapnutou automatickou kontrolu I/O operaci (Options -> Compiler -> I/O checking nebo {$I+}). Vetsinou jsou docela srozumitelne a dobre se odstranuji, takze je zvlast popisovat nebudu. Pokud potrebujete, aby kvuli temto chybam program nepadal (napr. testovani existence souboru jeho pokusnym otevrenim a zavrenim a kontrolou Ioresultu), vypnete automatickou kontrolu I/O. Pokud pak nejaka chyba nastane, vsechny nasledujici I/O operace budou az do zavolani Ioresultu ignorovany. 106 Invalid numeric format =========================== Znamena "neplatny format cisla". Objevuje se, pokud ctete cislo pomoci Read nebo Readln z klavesnice nebo textoveho souboru a to, co se precte, neni cislo: carka misto desetinne tecky, obsahuje pismena nebo jine paznaky apod.. Reseni: davat pozor, co tukate do klavesnice nebo co nacitate ze souboru. Nebo jistejsi zpusob: nactete misto cisla retezec a ten pak prevedte na cislo procedurou Val. Pokud bylo cislo zadane spatne, Val vrati chybovy kod, ale program nespadne a muzete treba nechat zadat cislo znovu a lepe. 200 Division by zero ===================== Znamena "deleni nulou". Celkem nepotrebuje komentar: nulou se proste delit nesmi. Reseni: osetrit vypocty tak, aby se v nich nulou delit nedalo. Ovsem pokud program na tuto chybu umre hned po spusteni a jste si jisti, ze jste ji urcite nezavinili vy, hledejte chybu v samotnem TP 7, a to konkretne v jednotce CRT. Borlandi totiz zvrzali inicializaci cekacich konstant pro proceduru Delay, kde na procesorech rychlejsich nez cca 200 MHz k deleni nulou dochazi. Reseni: bud jednotku CRT nepouzivejte (celkem neni problem - vsechny veci pro cteni klavesnice, vystup na textovou obrazovku i obsluhu PC-Squeakeru si muzete napsat sami nebo nekde stahnout, treba hned na moji strance, viz uvod) nebo si nekde sezente patch a jednotku CRT opravte. A nebo si stahnete rovnou cely opatchovany TP7 (taky u me, ale pssst! :-) ). 201 Range check error ====================== Znamena "chyba pri kontrole rozsahu". Objevuje se jen prokud je zapnuta kontrola rozsahu (Options -> Compiler -> Range checking nebo direktiva {$R+}), a to pokud nejaka promenna "pretece" (treba kdyz chceme zvysit o 1 promennou typu byte s aktualni hodnotou 255) nebo pokud index pole dosahl hodnoty mimo meze deklarovane v definici toho pole (napr. pole array[1..10] of neco a snazime se neco delat s polozkou pole[11]). Reseni: pokud je dane preteceni opravdu nezadouci, bude nutne upravit program tak, aby k nemu nedochazelo: pouzit "vetsi" promenne (longint misto integeru, word misto bytu apod.) nebo zvetsit rozsah prislusneho pole. Pokud vam dane preteceni nevadi (treba opravdu chci, aby byte s hodnotou 255 zvyseny o 1 pretekl a tim v nem zustala hodnota 0), vypnete kontrolu rozsahu ({$R-} nebo pres Options). Toto se take casto vyuziva pri tvorbe dynamickych poli. Deklaruji si pomocny typ - sablonu, treba: array[0..0] of neco a ukazatel na nej. Pak vytvorim pomoci Getmem dynamickou promennou. Protoze se rozsah nekontroluje, muzu do pole zapisovat kam chci, ale zase je na mne, abych nepsal mimo alokovanou dyn. promennou, protoze jinak je z toho "Program provedl neplatnou aplikaci a bude ukoncen...". 202 Stack overflow error ========================= Znamena "preteceni zasobniku". Objevuje se, pokud je zavolano prilis mnoho procedur zaroven, hlavne pri rekurzi. Reseni: bud zvetsit velikost zasobniku (Options -> Memory sizes -> Stack size nebo direktiva {$M...}) nebo se postarat o to, aby nepretekal. Tato chyba je totiz casto zpusobena nekonecnou rekurzi, takze staci tuto smycku najit a odstranit. Da se take vypnout kontrola zasobniku (Options -> Compiler -> Stack checking nebo direktiva {$S-}). Pak program sice OBVYKLE nespadne, ale muzou se stat i daleko horsi veci, takze tuto variantu nedoporucuji. 203 Heap overflow error ======================== Znamena "preteceni hromady", tedy casti pameti vyhrazene pro alokaci dynamic- kych promennych. Vznika, pokud se pokousite alokovat promennou (Getmem nebo New) a pamet uz na ni nestaci. Prvni moznost reseni: pokuste se zvetsit hromadu (Options -> Memory sizes -> -> zvysit High heap limit; to same jde pres direktivu {$M...}). Obvykle ale uz je nastavena na maximum (neco kolem 640 KB), takze tady neporidime. Ucinnejsi byva provest stejne kroky, jake jsou popsany uplne na zacatku tohoto souboru u chyby 1: Out of memory. Hlavne se ale podivejte, jestli nekde nemate alokaci pameti (Getmem, New) v nekonecnem (nebo aspon hodne dlouhem) cyklu, a jestli vsechny dynamicke promenne, ktere nepotrebujete, zase rusite (Freemem, Dispose) nebo jestli vam nekde nezustavaji ztracene dynamicke promenne (new(ukazatel); ukazatel:=...;). Porad nic? Pak nezbyva nez si pohrat s organizaci dat v programu, aby tolik pameti nepotreboval. Neukladate nahodou jeden stejny obrazek vickrat, kdyz by stacilo ho ulozit jednou a pak se na nej z nekolika mist odkazovat? Nebylo by lepsi nejaka data radsi nacist z externiho souboru dvakrat, nez je celou dobu uchovavat v pameti? Nebylo by lepsi misto spojoveho seznamu pouzit o neco uspornejsi pole, nebo aspon misto obousmerneho jednosmerny? Take nezapomente, ze cokoli, co alokujete na hromade, bude mit vzdy velikost v nasobcich 16, tedy minimalne 16 B. Kdyz alokujete dynamickou promennou o velikosti 5 B, stejne zabere celych 16 - na to pozor hlavne u dlouhych spojovych seznamu. Pokud pamet nadale nestaci a nechcete porad hrabat do uloznych souboru, muzete ukladat data do rozsirene pameti - XMS (prislusnou jednotku si muzete ode me stahnout, zvladnout by mela az 64 MB). Porad malo? Prejdete na 32bitovy prekladac a do chraneneho rezimu, ale o tom tenhle manual neni. 204 Invalid pointer operation ============================== Tj. "neplatna operace s ukazatelem". Vznika, pokud se pokousite dealokovat (Dispose nebo Freemem) neexistujici dynamickou promennou - prislusny ukazatel ma bud hodnotu Nil nebo ukazuje nekam do pr&*$* a ne na tu promennou. Reseni: dukladne si prohlednete usek programu od alokace promenne (Getmem nebo New) az po tu problematickou dealokaci a koukejte, co se s tim ukazatelem PRESNE deje. Nemenite nekde hodnotu ukazatele (ukazatel:=...) misto abyste menili hodnotu te dynamicke promenne (ukazatel^:=..., pozor take u Move)? Nevynu(i)lovali jste ho omylem nekde? A byla ta promenna opravdu alokovana? Nebyla tam nekde podminka if neco then Getmem nebo New, ale uz zadna podminka u Freemem nebo Dispose? Neni alokace pred nejakym cyklem a zruseni omylem v tom cyklu misto za nim, takze se provede vickrat? 207 Invalid floating point operation ===================================== Znamena "neplatna operace pri pocitani s realnym cislem". Vyskyt: 1) Cislo, ktere jste nechali zaokrouhlit pomoci Round nebo Trunc se neveslo do Longintu. Reseni: pred zaokrouhlenim zkontrolujte velikost cisla, pokud se nevejde do intervalu -2147483648..2147483647, o zaokrouhleni se nepokousejte. 2) Chteli jste pocitat druhou odmocninu (Sqrt) ze zaporneho cisla. Reseni: zkontrolujte, jakych hodnot to cislo muze nabyvat. Zalezi na okolnostech, co zrovna pocitate, ale muzete bud zapornym hodnotam nejak zabranit nebo treba pokud je cislo zaporne, vynulovat ho nebo pouzit Abs. Dlouho jsem nemohl prijit na to, proc se mi tahle chyba objevuje pri vypoctu vzdalenosti dvou bodu v rovine pres obycejnou Pythagorovu vetu. Pak mi doslo, ze souradnice bodu byly integery a kdyz jsem z nich pocital druhe mocniny, trochu pretekly a do nejvyssiho bitu se dostala jednicka. U wordu by to nevadilo, ale u integeru to znamena minus - aha! Stacilo misto integeru pouzit longint a bylo po pretekani. 3) Chteli jste pocitat logaritmus (Ln) z cisla mensiho nebo rovneho nule, coz nejde. Reseni: podobne jako u odmocniny - hlidejte si hodnoty. 4) Pretekl zasobnik koprocesoru 8087. To se mi jeste nestalo, takze neporadim. 210 Object not initialized =========================== Znamena "objekt (tj. promenna typu object) nebyl inicializovan". Kazdy objekt pred prvnim pouzitim musime inicializovat - priradit nejake hodnoty vsem jeho polozkam. Pokud to neudelame, jejich hodnoty jsou nedefino- vane (tj. nevime jake) a muzou zpusobit problemy. Osobne jsem tuto hlasku jeste nevidel, ale kvuli neinicializovanemu objektu mi parkrat program proste spadl. Program provedl neplatnou aplikaci a bude ukoncen. [Zavrit] [Podrobnosti] Program provedl nepovolenou operaci a bude ukoncen... atd. =========================================================================== Tohle neni ani klasicka chybova hlaska Pascalu ani interni Run-time error message jednotky System. Myslim tim nase "oblibene" windowsovske okno, ktere se od chvile, kdy opustime ty nejjednodussi programatorske zacatky, objevuje pomerne casto. Pokud pracujeme v DOSu, vetsinou tato chyba zpusobi zaseknuti pocitace, coz se obvykle spravi resetem. Vyskyt c.1: mame proceduralni promennou nebo ukazatel predstavujici adresu procedury. Tuto proceduru zavolame ve chvili, kdy adresa neni platna, takze program skoci neznamo kam. Vyskyt c.2: mame ukazatel a zapiseme neco na adresu, na kterou ukazuje, jenze neukazuje na zadnou korektne definovanou nebo alokovanou statickou nebo dynamickou promennou, ale nekam do haje (a my to obvykle nevime nebo prehledneme). Vyskyt c.3: mame pole, je celkem jedno jestli staticke nebo dynamicke, a vypnutou kontrolu rozsahu (napr. {$R-}). Program tedy nezkontroluje, jestli opravdu zapisujeme do pole nebo mimo nej. Kdyz tedy zapiseme neco na prvek pole s indexem mimo deklarovany rozsah (nebo rozsah velikosti alokovaneho dynamickeho pole, ktery si ale musime pamatovat sami), zapise se do pameti, ktera "neni nase", kde je treba ulozeno neco jineho a co kdyz prepiseme, je z toho prusvih. Obecne je tato chyba zpusobena tim, ze v pameti NECO ZAPISUJEME TAM, KAM NEMAME nebo nechame program skocit nekam, kde NEJSOU INSTRUKCE, ALE JINA DATA, coz okamzite vede k prvni moznosti. Tohle si pamatujte, o nicem jinem to obvykle neni. Reseni: tahle chyba patri k tem obtizneji odstranitelnym. Je potreba prekon- trolovat vsechny pouzite adresy, jestli opravdu v okamziku pouziti maji spravne hodnoty, a skutecne aktualni rozmery dynamickych poli a promennych (zvlaste pri pouziti pretypovaneho obecneho ukazatele - ukazujeme vubec na to, na co myslime, ze ukazujeme?). V asm kodech je tato chyba casto zpusobena [ end ] zmenou registru DS, ktery uchovava segmentovou cast adresy globalnich promennych. Proto pred kazdou rucni zmenou DS ho musime ulozit (push) a po pouziti opet obnovit (pop), zaroven ve chvili, kdy je jeho hodnota zmenena, nesmime pristupovat k zadne globalni promenne, protoze jejich adresa, ktera byla v DS, je ted zmenena, takze bychom se dostali k uplne jinym datum!!! U ruznych asm procedur pak musime davat pozor na to, ktere registry meni, a [ end ] podle toho se chovat pred jejich zavolanim z jineho asm kodu a po nem. [ end ] Take pozor na procedury pro obsluhu preruseni (interrupt). Nemenite nahodou nejake promenne, ktere menit nechcete? Dalsi uskali - dynamicke promenne jako parametr volany odkazem (parametr procedury nebo funkce deklarovany se slovem Var) a hodnotou (bez Var). Dejme tomu, ze mame treba zaznam (record), jehoz jedna polozka je ukazatel. Pokud ho predame nejake procedure jako parametr volany hodnotou, vytvori se cely zaznam jako lokalni promenna s prislusnymi hodnotami polozek, ale pozor, sice ten ukazatel bude ukazovat na stejnou adresu jako original, ale ta dynamicka pro- menna bude stale jen ta jedna puvodni, zadna lokalni se nevytvori! Jestli zmenime hodnotu toho ukazatele (napr. nejakou alokaci), zmeni se jen lokalne a skutecny ukazatel bude ukazovat tam, kam ukazoval predtim. Jestli ale zmenime hodnotu te dynamicke promenne, na kterou ukazuje, skutecne se zmeni!! Pokud ten zaznam predame jako var-parametr, lokalni promenna se nevytvori, bude se menit primo skutecny zaznam. Pokud tedy zmenime hodnotu ukazatele, zustane zmenena. ************************* A to je vse, pratele. ***************************** Preji mnoho uspechu pri vychytavani much, trpelivost a pevne nervy :-) (c) Mircosoft 23.4.2007