This shows you the differences between two versions of the page.
|
so:teme:general [2019/02/24 20:41] mbarbulescu [Cele mai frecvente greșeli întâlnite în teme] |
so:teme:general [2020/03/09 09:41] (current) razvan.deaconescu [Listă depunctări] |
||
|---|---|---|---|
| Line 9: | Line 9: | ||
| * Dacă nu sunteți siguri pe modul vostru de indentare, folosiți [[http://www.gnu.org/software/indent/ | indent]] sau [[http://astyle.sourceforge.net/ | astyle]]. | * Dacă nu sunteți siguri pe modul vostru de indentare, folosiți [[http://www.gnu.org/software/indent/ | indent]] sau [[http://astyle.sourceforge.net/ | astyle]]. | ||
| * Pentru cei care folosesc vim, puteți porni de la acest {{ :so:teme:vimrc.zip|vimrc}} | * Pentru cei care folosesc vim, puteți porni de la acest {{ :so:teme:vimrc.zip|vimrc}} | ||
| - | * Creați un README relevant care să nu reproducă enunțul sau comentariile din cod și care să ajute la înțelegerea soluției alese. | + | * Creați un README relevant care să nu reproducă enunțul sau comentariile din cod și care să ajute la înțelegerea soluției alese. Găsiți mai jos în secțiunea README - how to recomandările echipei de SO pentru realizarea README-ului, puteți folosi acestea ca un template când îl scrieți. |
| * Folosiți lista de discuții dacă aveți întrebări referitoare la coding style sau best practices. | * Folosiți lista de discuții dacă aveți întrebări referitoare la coding style sau best practices. | ||
| * Pentru abordări de evitat (bad practices) vă recomandăm lectura articolelor despre [[http://en.wikipedia.org/wiki/Anti-pattern#Software_engineering | Anti-patterns]] și [[https://en.wikipedia.org/wiki/Code_smell | Code smells]]. | * Pentru abordări de evitat (bad practices) vă recomandăm lectura articolelor despre [[http://en.wikipedia.org/wiki/Anti-pattern#Software_engineering | Anti-patterns]] și [[https://en.wikipedia.org/wiki/Code_smell | Code smells]]. | ||
| Line 15: | Line 15: | ||
| * Recomandăm să folosiți tehnici de [[http://en.wikipedia.org/wiki/Unit_testing | unit testing]]. | * Recomandăm să folosiți tehnici de [[http://en.wikipedia.org/wiki/Unit_testing | unit testing]]. | ||
| * Găsiți [[http://en.wikipedia.org/wiki/List_of_unit_testing_frameworks | aici]] o serie de framework-uri de unit testing. | * Găsiți [[http://en.wikipedia.org/wiki/List_of_unit_testing_frameworks | aici]] o serie de framework-uri de unit testing. | ||
| + | * Pentru cod C recomandăm https://cmocka.org/ | ||
| + | * Pentru cod C++ recomandăm [[https://github.com/google/googletest|Google Test]] și [[https://github.com/google/googlemock|Google Mock]] | ||
| + | |||
| ===== Listă depunctări ===== | ===== Listă depunctări ===== | ||
| - | *Temele care nu se compilează sau nu rulează, indiferent de motive, vor primi punctaj 0; folosiți sistemul [[https://elf.cs.pub.ro/vmchecker/ui/ | vmchecker]] pentru a verifica rularea/compilarea corespunzătoare a temelor | ||
| + | * Temele care nu se compilează sau nu rulează, indiferent de motive, vor primi punctaj 0; folosiți sistemul [[https://elf.cs.pub.ro/vmchecker/ui/ | vmchecker]] pentru a verifica rularea/compilarea corespunzătoare a temelor. | ||
| + | * Pe sistemele de operare general purpose de tipul Linux, *OS, Windows, FreeBSD, cu biblioteci standard C complexe, resursele proprii / nepartajate procesului (memorie alocată, fișiere deschise, thread-uri create) sunt eliberate și închise la încheierea procesului (exit). Pe aceste sisteme nu e nevoie să eliberați explicit înainte de exit; pot există medii specifice în care acest lucru nu se întâmplă. Cea mai bună practică (best practice) este să eliberați explicit resursele ca să acoperiți toate situațiile. | ||
| ==== Funcționalitate ==== | ==== Funcționalitate ==== | ||
| *-0.2: accesarea unor zone de memorie nevalide (care nu rezultă în mesaj de eroare de tipul "Segmentation fault"): buffer overflow, lucru neadecvat cu funcții pe șiruri; pentru depistarea accesărilor invalide puteți folosi [[http://ocw.cs.pub.ro/courses/so/laboratoare/laborator-05#valgrind | valgrind]]; | *-0.2: accesarea unor zone de memorie nevalide (care nu rezultă în mesaj de eroare de tipul "Segmentation fault"): buffer overflow, lucru neadecvat cu funcții pe șiruri; pentru depistarea accesărilor invalide puteți folosi [[http://ocw.cs.pub.ro/courses/so/laboratoare/laborator-05#valgrind | valgrind]]; | ||
| Line 68: | Line 72: | ||
| === Documentație === | === Documentație === | ||
| - | *-0.1: surse nesemnate; | ||
| *-0.1: comentarii inadecvate: comentarii nerelevante sau absente; | *-0.1: comentarii inadecvate: comentarii nerelevante sau absente; | ||
| *-0.1: comentarii cu C99 (''%%//%%'' in loc de ''/%%*%% %%*%%/'') | *-0.1: comentarii cu C99 (''%%//%%'' in loc de ''/%%*%% %%*%%/'') | ||
| *-0.2: README necorespunzător: nu se descrie soluția, se indică doar comentarii din sursă, copy paste la enunț sau la comentarii. | *-0.2: README necorespunzător: nu se descrie soluția, se indică doar comentarii din sursă, copy paste la enunț sau la comentarii. | ||
| + | |||
| + | ===== README - how to ===== | ||
| + | |||
| + | === Organizare === | ||
| + | |||
| + | Explicație pentru structura creată (sau soluția de ansamblu aleasă): | ||
| + | |||
| + | **Obligatoriu:** | ||
| + | |||
| + | * De făcut referință la abordarea generală menționată în paragraful de mai sus. Aici se pot băga bucăți de cod/funcții - etc. | ||
| + | * Consideri că tema este utilă? | ||
| + | * Consideri implementarea naivă, eficientă, se putea mai bine? | ||
| + | |||
| + | **Opțional:** | ||
| + | * De menționat cazuri speciale (corner cases), nespecificate în enunț și cum au fost tratate (în special dacă comentariile din cod nu le acoperă) | ||
| + | |||
| + | |||
| + | === Implementare === | ||
| + | |||
| + | * De specificat dacă întregul enunț al temei e implementat sau ce bucăți | ||
| + | * Dacă există funcționalități extra, pe lângă cele din enunț - dați o descriere succintă (maximum 3-4 rânduri/funcționalitate) și motivarea lor (maximum 1-2 fraze) | ||
| + | * De specificat funcționalitățile lipsă din enunț, dar necesare realizării complete a temei (dacă există) și de menționat dacă testele reflectă sau nu acest lucru | ||
| + | * Dificultăți întâmpinate | ||
| + | * Lucruri interesante descoperite pe parcurs | ||
| + | |||
| + | === Cum se compilează și cum se rulează? === | ||
| + | |||
| + | * Explicație, ce biblioteci linkează, cum se face build | ||
| + | * Cum se rulează executabilul, se rulează cu argumente (sau nu) | ||
| + | |||
| + | === Bibliografie === | ||
| + | |||
| + | * Resurse utilizate - toate resursele publice de pe internet/cărți/code snippets, chiar dacă sunt laboratoare de SO | ||
| + | |||
| + | === Git === | ||
| + | |||
| + | Link către repo-ul de git folosit pentru localizarea surselor | ||
| + | |||
| + | === Ce să NU conțină un readme === | ||
| + | |||
| + | * Detalii de implementare despre fiecare funcție/fișier în parte | ||
| + | * Fraze lungi care să ocolească subiectul în cauză | ||
| + | * Răspunsuri și idei neargumentate | ||
| + | * Comentarii copy/paste din cod și TODO-uri | ||
| ===== Cele mai frecvente greșeli întâlnite în teme ===== | ===== Cele mai frecvente greșeli întâlnite în teme ===== | ||
| - | * Neverificarea valorilor de retur a apelurilor de sistem și implicit netratarea erorilor. Aici sunt două variante: | + | * Neverificarea valorilor de retur a apelurilor de sistem și implicit netratarea erorilor. Aici sunt două variante: |
| - | * fie se termină programul brusc prin folosirea unui [[http://man7.org/linux/man-pages/man3/assert.3.html|assert]] sau a [[:so:laboratoare:resurse:die|macro-ului DIE]] | + | * fie se termină programul brusc prin folosirea unui [[http://man7.org/linux/man-pages/man3/assert.3.html|assert]] sau a [[:so:laboratoare:resurse:die|macro-ului DIE]] |
| - | * dacă eroarea nu este "neapărat" fatală și permite continuarea rulării programului trebuie acumulate undeva erorile și se recomandă folosirea unor [[https://gist.github.com/tomaslibal/3a9b04a97ae3d1b2373f|debug prints]] | + | * dacă eroarea nu este "neapărat" fatală și permite continuarea rulării programului trebuie acumulate undeva erorile și se recomandă folosirea unor [[https://gist.github.com/tomaslibal/3a9b04a97ae3d1b2373f|debug prints]] |
| <note important> | <note important> | ||
| - | Se preferă abordarea din primul bullet. Dacă un apel low-level de sistem pică este indicată de cele mai multe ori o problemă mai adâncă. | + | Se preferă abordarea din primul bullet (DIE/assert). Dacă un apel low-level de sistem pică este indicată de cele mai multe ori o problemă mai adâncă la nivelul sistemului și preferăm un die general. |
| </note> | </note> | ||
| - | * Alocarea dinamică atunci când se poate folosi cea statică (mai puțin heap consumat și mai puțini ciclii!) | + | * Alocarea dinamică atunci când se poate folosi cea statică (mai puțin heap consumat și mai puțini ciclii!) |
| - | * exemplu: cerința spune că un buffer de comenzi are maxim 256 de caractere. Mai bine alocăm un ''char cmd[256]'' | + | * exemplu: cerința spune că un buffer de comenzi are maxim 256 de caractere. Mai bine alocăm un ''char cmd[256]'' |
| - | decât ''char *cmd = malloc(256 * sizeof(char));'' | + | * tot în acest caz (și altele similare) întâlnim des folosirea de valori hardcodate. Corect este: |
| - | * tot în acest caz (și altele similare) întâlnim des folosirea de valori hardcodate. Corect este: | + | |
| <code C> | <code C> | ||
| /* Undeva într-un fișier .h */ | /* Undeva într-un fișier .h */ | ||
| Line 97: | Line 143: | ||
| char cmd[MAX_CMD_BUF_SIZE]; | char cmd[MAX_CMD_BUF_SIZE]; | ||
| </code> | </code> | ||
| - | |||
| - | * Neînchiderea/necurățarea resurselor folosite: | ||
| - | * Memorie alocată dinamic (cu ''malloc/calloc'') neeliberată folosind ''free'' - se poate verifica utilizând ''valgrind'' | ||
| - | * Fișiere deschise cu ''open'' care nu mai sunt închise folosind ''close'' - se poate folosi opțiunea ''--track-fds'' a ''valgrind'' | ||
| - | * Procese pornite cu ''fork'' după care nu se face ''wait/waitpid'' - rezultă în apariția unor procese zombie | ||
| - | * Implementare nemodulară, într-un singur fișier. Exemplu: avem de implementat un hashtable cu bucket-urile fiind liste înlănțuite | + | |
| - | * semnăturile funcțiile, macro-uri, definiții pentru structuri utile lucrului cu liste se pun intr-un header ''list.h'' | + | * Neînchiderea/necurățarea resurselor folosite: |
| - | * implementările funcțiilor de mai sus se fac în sursa ''list.c'' | + | * Memorie alocată dinamic (cu ''malloc/calloc'') neeliberată folosind ''free'' - se poate verifica utilizând ''valgrind'' |
| - | * semnăturile funcțiile, macro-uri, funcție de hash, definiții pentru structuri utile lucrului cu hashtable se pun intr-un header ''hashtable.h'' | + | * Fișiere deschise cu ''open'' care nu mai sunt închise folosind ''close'' - se poate folosi opțiunea ''--track-fds'' a ''valgrind'' |
| - | * implementările funcțiilor de mai sus se fac în sursa ''hashtable.c'' | + | * Procese pornite cu ''fork'' după care nu se face ''wait/waitpid'' - rezultă în apariția unor procese zombie |
| - | * lucrul cu apeluri de sistem (e.g. wrappere) sau macro-uri de assert se pot pune într-un ''util.h'' și ''util.c'' | + | |
| + | * Implementare nemodulară, într-un singur fișier. Exemplu: avem de implementat un hashtable cu bucket-urile fiind liste înlănțuite | ||
| + | * semnăturile funcțiile, macro-uri, definiții pentru structuri utile lucrului cu liste se pun intr-un header ''list.h'' | ||
| + | * implementările funcțiilor de mai sus se fac în sursa ''list.c'' | ||
| + | * semnăturile funcțiile, macro-uri, funcție de hash, definiții pentru structuri utile lucrului cu hashtable se pun intr-un header ''hashtable.h'' | ||
| + | * implementările funcțiilor de mai sus se fac în sursa ''hashtable.c'' | ||
| + | * lucrul cu apeluri de sistem (e.g. wrappere) sau macro-uri de assert se pot pune într-un ''util.h'' și ''util.c'' | ||
| + | * **NOTĂ:** Funcțiile și variabilele globale interne unui modul (e.g. funcții folosite **doar** în ''list.c'') se declară folosind calificatorul ''static''. | ||
| <note important> | <note important> | ||
| Line 118: | Line 166: | ||
| Sursa: http://wiki.c2.com/?CodeForTheMaintainer | Sursa: http://wiki.c2.com/?CodeForTheMaintainer | ||
| </note> | </note> | ||
| - | |||
| - | |||
| - | |||