===== Úkol 1 ===== 1. úkol se skládá ze čtyř malých úloh: * Načtení matice ze vstupu * Výpis tabulky na výstup * Verifikace formátovaného vstupu * Práce s dlouhými čísly K dispozici máte {{:courses:a7b36pjc:ukoly:small1.zip|archiv}} obsahující [[https://github.com/philsquared/Catch|Catch]] testy, které vám zkontrolují vaše řešení, a dva další soubory. Hlavičkový soubor ''small1.hpp'' obsahuje deklarace funkcí, které máte implementovat, a zdrojový soubor ''small1.cpp'', který obsahuje jejich prázdná těla. Archiv se tedy dá po stažení zkompilovat a spustit, ale neprojdou testy. ==== Co odevzdat? ==== Odevzdávejte soubor ''.zip'', který obsahuje jeden nebo více souborů ''.cpp'', ve kterých jsou implementované funkce z hlavičkových souborů z domácího úkolu. Vámi odevzdané soubory by neměly být schované v podsložce a prosíme vás, abyste neodevzdávali soubory vašeho IDE((Pokud má váš úkol 1 MB před zabalením, pravděpodobně toho odevzdáváte příliš. Pokud má váš úkol 1 MB po zabalení, *určitě* toho odevzdáváte příliš.)). Žádný ze souborů s testy není třeba odevzdávat. ==== Catch ==== ''Catch'' je framework pro psaní testů pro C%%++%% kód. Základní použití je jednoduché, stačí v nějakém souboru deklarovat makro ''CATCH_CONFIG_MAIN'' před includováním hlavičky ''catch.hpp'' a v ostatních souborech se již můžou psát testy. Následně stačí zkompilovat zdrojové soubory a spustit výsledný program, čímž se provedou a vypíšou výsledky testů. V archivu, který máte od nás, najdete ''catch.hpp'', hlavičku s aktuální verzí testovací hlavičky, ''tests-main.cpp'', zdrojový soubor s definicí makra ''CATCH_CONFIG_MAIN'', a ''tests-small1.cpp'', ve kterém jsou testy pro vaši implementaci. ==== Valgrind ==== Všechny odevzdané úkoly jsou kontrolovány za použití [[https://cs.wikipedia.org/wiki/Valgrind|Valgrindu]]. Valgrind je schopen najít spoustu chyb, které se normálně nemusí projevit, a v případě, že nějakou najde, bude vám sražena část bodů z domácího úkolu. ===== Rady ===== ==== Užitečné hlavičky ==== V různých úkolech si můžete ulehčit práci použitím standardních knihoven. V tomto doporučujeme podívat se blíže na [[http://en.cppreference.com/w/cpp/io/manip|hlavičku ]] a samozřejmě na věci, které se probíraly na cvičení (například ''std::stringstream''). ==== Dlouhá doba kompilace ==== Pokud kompilujete z příkazové řádky((Pokud ne, vyřeší za vás tyto věci vaše IDE.)), pravděpodobně zjitíte, že vám kompilace běží velmi dlouho (5-10s). Protože nejdelší dobu se kompiluje soubor ''tests-main.cpp'', který se nebude měnit, vyplatí se ho zkompilovat do tzv. objektového souboru. Objektové soubory jsou mezikrok mezi implementačními soubory a fungujícím programem. Pokud spustíte kompilátor s argumentem ''-c'', místo binárky se vám vytvoří objektové soubory. Volání clang++ -std=c++14 tests-small.cpp tests-main.cpp -c vám vytvoří soubory ''tests-small.o'' a ''tests-main.o'', které pak můžete použít při kompilaci místo ''tests-small.cpp'' a ''tests-main.cpp''. Pozor, soubor s vaší implementací takto nahradit nemůžete, protože ''.o'' soubory se automaticky neaktualizují při změnách původních ''.cpp'' souborů. Výsledné volání pro kompilaci tedy bude zhruba takovéto clang++ -std=c++14 tests-small.o tests-main.o small1.cpp -o small1 a kompilace bude trvat výrazně kratší dobu. ==== Čtení kompilačních chyb ==== Pokud se něco pokazí při kompilaci, C%%++%% je schopno generovat opravdu dlouhé chyby. Ve skutečnosti je z nich obvykle relevantní pouze krátká část, protože výpis má formu kompilačního stacktrace -- při kompilaci jaké funkce vznikla chyba a proč byla daná funkce kompilována. To znamená, že při čtení kompilační chyby je potřeba najít první výpis, který je ve vašem kódu, protože právě ten způsobuje danou chybu. Kompilátory dále mají tendenci přidat na konec výpisu chyby informace o všem, o co všechno se pokusili. Co to znamená, ukážeme na příkladu: #include int main(){ int i; std::cout >> i; std::cout << i; } Tento kus kódu se snaží načíst a vypsat jedno číslo, ale místo ''std::cin'' je v něm použit ''std::cout''. Když ho proženeme skrz Clang, získáme tento výpis: | \\ test.cpp:5:15: error: invalid operands to binary expression ('ostream' (aka 'basic_ostream') and 'int') std::cout >> i; ~~~~~~~~~ ^ ~ /usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/../../../../include/c++/5.3.1/streambuf:168:9: note: candidate template ignored: could not match 'basic_istream' against 'basic_ostream' operator>>(basic_istream<_CharT2, _Traits2>&, ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/../../../../include/c++/5.3.1/istream:756:5: note: candidate template ignored: could not match 'basic_istream' against 'basic_ostream' operator>>(basic_istream& __in, unsigned char& __c) ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/../../../../include/c++/5.3.1/istream:761:5: note: candidate template ignored: could not match 'basic_istream' against 'basic_ostream' operator>>(basic_istream& __in, signed char& __c) ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/../../../../include/c++/5.3.1/istream:803:5: note: candidate template ignored: could not match 'basic_istream' against 'basic_ostream' operator>>(basic_istream& __in, unsigned char* __s) ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/../../../../include/c++/5.3.1/istream:808:5: note: candidate template ignored: could not match 'basic_istream' against 'basic_ostream' operator>>(basic_istream& __in, signed char* __s) ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/../../../../include/c++/5.3.1/bits/istream.tcc:923:5: note: candidate template ignored: could not match 'basic_istream' against 'basic_ostream' operator>>(basic_istream<_CharT, _Traits>& __in, _CharT& __c) ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/../../../../include/c++/5.3.1/bits/istream.tcc:955:5: note: candidate template ignored: could not match 'basic_istream' against 'basic_ostream' operator>>(basic_istream<_CharT, _Traits>& __in, _CharT* __s) ^ 1 error generated. Hned první řádek výpisu se odkazuje do našeho kódu a zhruba říká, kde je chyba (nemůžeme použít operátor ''%%>>%%'' na výstupní proud a int), ale výpis obsahuje spoustu dalších řádků, které popisují, co všechno kompilátor zkusil, než došel k tomu, že to je chyba. V tomto případě vyzkoušel různá přetížení operátoru ''%%>>%%'', ale zjistil, že žádné z nich nepasuje pro daný výraz. ==== Undefined reference error ==== Pokud vám linkování programu selže s chybou během linkování, pravděpodobně to znamená, že nelinkujete vše, co máte. * Pokud vám chybí funkce ''main'', nejspíše kompilujete pouze soubor s vaší implementací a nekompilujete soubory s testy. * Pokud vám chybí funkce, které máte implementovat, nejspíše kompilujete pouze soubory s testy a nekompilujete s nimi i vaši implementaci. * Pokud vám chybí funkce s ''Catch::'' v názvu, nekompilujete tests-main.cpp. ==== Časově náročné testy ==== Úkol obsahuje časově náročné testy, které jsou při normálním spuštění vypnuté. Pokud je chcete spustit, musíte zavolat výslednou binárku s argumentem ''[.long]'': ''small1 [.long]'' Silně doporučujeme ho spouštět pouze v optimalizované binárce, tj. stavět v Release módu nebo na příkazové řádce s parametrem ''-O3''.