O noua propunere

Zarva mare in comunitatea expertilor, caci 0ptr iar e pus pe sotii. Dupa ce s-a lamurit cu Regula 0 a codului portabil, a revenit cu o intrebare parca special facuta pentru a-l activa pe Silviu Virgula Ardelean: cum ati implementa atoi()?

Intrebarea asta e pentru miner ca un laser pointer pentru o pisica: irezistibila. Silviu traieste pentru momentele astea, cind cineva pune o intrebare banala si el crede ca stie raspunsul, pentru ca ii permit sa-si afirme si sa-si confirme statutul de connaisseur. Cu serotonina refulind prin nas si urechi, el a atins duios tastatura si a scris cuvintele ce-i sint atit de dragi: Eu propun urmatoarea implementare.

Propunerea nu dezamageste. Prin truda afunda, ortacul scoate din abataj o noua floare de mina desavirsita, un memento al zbuciumului ce-i cuprinde fiinta de fiecare data cind se vede pus in fata unei masini de scris automate. Dat fiind ca el n-are un compilator in cap, o sa fac eu pe compilatorul si voi incerca sa descifrez linie cu linie ce se petrece in mintea greu incercata a unui miner cu 9 ani de experienta in C++.

bool isNegative = (*pChar == '-') ? true : false;

Ostilitatile incep in forta. Silviu nu are incredere in compilatoare si alte “tool-uri automate”, asa ca foloseste operatorul ? pentru a converti true la true si false la false. Asta e doar pasul 1 din planul lui. Cind va implini 10 ani de experienta in C++, isi va autoimpune sa transeze definitiv problema bool-ului prin urmatoarele tipuri de constructii:

bool a = true ? true : false;
bool b = false ? true : false;
if( ((true == a ? true : false) || (false == b ? true : false)) ? true : false)
    a = b ? true : false;

Urmeaza o prima trecere prin string, cu scopul de a verifica daca instructiunile de branch ale procesorului functioneaza corect sub stres:

while (*pChar != '\0')
{
   if ((isNegative && length == 1 && (*pChar != '-') && (*pChar < '0' || *pChar > '9')) ||
      (length > 0 && (*pChar < '0' || *pChar > '9')))
         break;

   length++;
      pChar += sizeof(char);
}

If-ul asta e reprezentativ pentru miner. In opinia lui, “loop-ul ala e un ‘strlen()’ mai special”. Da, special ca aia care baga cubul in gaura rotunda. Pe Silviu nu l-a dus capul sa incrementeze pointerul ala nenorocit daca string-ul incepe cu minus, dar el e puternic, asa ca a impins cit a putut de tare cubul si pina la urma a intrat in gaura. De asemenea, observam citeva reguli de stil bine conturate: ultima linie din bucla se indenteaza suplimentar, si se pun paranteze doar in jurul expresiilor care implica operatorul !=. length == 1 nu are nevoie de paranteze, dar *pChar != ‘-‘ are.

E important de observat si cum aduna Silviu sizeof(char) la pointer. Minerul a facut asta crezind ca e “best practice” sa fii explicit, ca nu stii cind treci la Unicode si trebuie sa aduni sizeof(wchar_t). Da, el habar n-are ce-i ala pointer arithmetic si chiar crede ca daca pChar era pointer la wchar_t, acolo trebuia sa adune mai mult de 1.

Ajungem, insa, la partea cu adevarat epica din cod, pe care o reproduc integral:

while (length > 0)
{
  decimal = 1;
  if (isNegative)
  {
     if (!isFirst)
     {
        length--;
        if (0 == length)
           break;
     }

     isFirst = true;
  }

  for (int i = 1; i < length; i++)
     decimal *= 10;

  ret_val +=   decimal * (int(*(pChar - length) - '0') % 10);
  length--;
}

Stiti cind ziceam ca ifdef-ul ala cu WIN32 e chintesenta incompetentei lui Silviu? Ei bine, bucla asta nu e la fel de concisa, dar tot e un imn al prostiei de o frumusete rar intilnita. Te astepti de la Silviu sa nu fie in stare sa faca atoi() intr-o singura trecere prin string, dar nici in cele mai umede vise nu speram sa ne ofere un asemenea festin al retardarii. Intii si intii, observam revenirea unui design pattern intilnit si in prima bucla: si asta verifica la fiecare iteratie daca a inceput. Ortacul nu e in stare sa scoata muia aia cu semnul in afara buclei, asa ca tot verifica daca bucla lui face ce fac buclele, si anume daca a reusit sa treaca la a doua iteratie.

Partea misto incepe insa dupa confirmarea abilitatii procesorului de a incrementa numere. Minerul a reusit sa faca atoi() in timp patratic. Dupa cum a mai demonstrat, el e un om simplu, deci prin definitie nu se preocupa de complexitate, dar ma surprinde iar in mod nespus de placut calculind exponentul ala in fiecare ciclu. Incercati sa va imaginati cum ar trebui sa decurga procesul deductiv prin care ajungi sa faci asa ceva. Eu n-am reusit. Voi va dati seama ca asta asa programeaza zilnic, la job? Si ca cineva ii da bani pentru ca sa scrie cod d-asta?

Ca sa incheie apoteotic, intii si-ntii mai arunca o sfidare in ochii compilatorului punind un cast explicit la int, spunindu-i parca “uite ba, iar fac eu treaba ta pentru tine”, dupa care baga un mod ca un chef care pune delicat cireasa in virful celui mai frumos tort pe care l-a facut pina acum. Pai de ce sa beneficieze doar partea booleana de verificari cu operatoru’ intrebare, si aia aritmetica nu? Ortacii programeaza defensiv, ca nu stii cind 9 se face brusc mai mare ca 10 si trebuie sa iei atitudine. De acum incolo, codul lui Silviu va fi de 3 ori mai sigur si mai conform cu standardele MISRA (despre care minerul a auzit linga automatul de cafea cind lucra la xerox la Siemens), caci aritmetica se va face in felul urmator:

pChar += sizeof(char) % 2;
int bytes = mb * (1024 % 1025);
int bits = bytes * (8 % 10);
int doi = 2 % 3;
int unu = 1 % doi;
for(int i = 0; i < size % (size + 1); ++i)

Ortacul si-a pregatit deja apararea: “nu are nimeni pretentia variantei perfecte”. Sa inceapa corecturile, deci.

LE: minerul a si dat prima replica: si-a editat al doilea post din thread si a scris ca patrujdoi sint eu, intr-o noua iesire de Poirot. Simt ca toata munca de reeducare pe care am dus-o aici tocmai s-a dus pe pula. A ajuns din nou sa creada ca eu sint jos8cal, 0ptr, patrujdoi si toti ceilalti care i-au aratat vreodata ca-i prost. Silviu se simte ca-n Matrix, el singur incojurat de o armata de eu. Pentru a doua oara intr-o singura zi s-a inundat de serotonina cind a putut face niste corecturi in codul lui patrujdoi, crezind ca ma corecteaza pe mine. Va dati seama ca a avut orgasm crezind ca m-a prins in sfirsit cu o greseala.

 

Tags: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,

13 Responses to “O noua propunere”

  1. thefatredguy Says:

    Deci asta cu pChar += sizeof(char) e epica. Io zic sa facem o cheta si sa-i cumparam “The C programming language”, poate dupa 10 ani de programare o sa invete si el pointer arithmetic.

  2. bullshit Says:

    Dar si raspunsurile lui Bivolaru Cucu “e cu pluta pe Prut”.

  3. Stefan Says:

    Da, Cucu e priceless:

    “Si o observatie suplimentara.
    Nici una dintre functiile CRT standard nu face verificare pentru overflow/buffer overrun/NULL parameter.
    Daca un intervievator se asteapta ca verificarile sa fie facute, fara sa specifice asta in mod explicit, atunci clar… e cu pluta pe Nicolina.”

  4. Becali Says:

    Pacat de cei care trebuie sa lucreze cu ineptiile debitate de oligofrenii astia.

  5. Codoiu Says:

    Lui Silviu nu ii e ciuda ca nu stie el, ii e ciuda ca stiu altii.

  6. un anonim Says:

    Eu ma tot mir ca ai avut rabdare sa diseci codul ala.. :)
    De-ar sti Silviu ca aia ce au facut kernel-ul la Linux au implementat atoi intr-o singura linie cu un apel la strtol…

  7. Mihnea Says:

    Mai toate libc-urile implementeaza atoi() cu un apel la strtol(), dar daca cineva te pune sa scrii tu unul vrea sa vada daca stii sa faci un while, nu daca stii sa apelezi o functie similara. Minerul nu stie sa faca un while.

  8. Vasile Says:

    io-s tare curios ce a facut 9 ani, parca ar fi fost in vacanta
    si acuma cu mare greu isi aminteste ce-i cu programarea

  9. Ion Says:

    Vasile, sper ca accepti ca e totusi o diferenta intre “cu greu isi aminteste” si “nu a priceput-o niciodata”.

  10. Vasile Says:

    asta clar ca asa e, eu speram, dar din cate am vazut e destul de activ omul, trist

  11. Un Troll Says:

    O noua propunere este aici: http://www.codexpert.ro/forum/viewtopic.php?f=13&t=1925
    Din pacate cu mare intarziere ma uit, dar acum ca m-am uitat… Silviule!!! cum de nu ai dat o mana de ajutor pe acolo? Sa nu vezi tu ca LordCronos pare sa aiba tot timpul din lume? Nu sa prezinte codul la scoala, la altceva ma refer.

    Ce zici, te tine? Hai ca e problema de-a 9-a!

  12. Un Troll Says:

    Mi scuzi, e un “exercetiu”

  13. Catalin++ Says:

    Ati fost detectati:)) Lui Mihnea i-a sters postul iar tie(Troll) nu mai au mult :))

Leave a Reply

Optionally add an image (JPEG only)