cod naspa

Acest forum este dedicat intrebarilor de programare care nu-si au locul in unul din celelalte forumuri
Post Reply
User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3776
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: cod naspa

Post by Ovidiu Cucu » 18 Feb 2010, 01:11

Silviu Ardelean wrote: PS. Cred ca ar fi cazul sa incheiam discutia cu sizeof(). :D
OK. Nu inainte de bucatica asta de cod

Code: Select all

switch(pMyStruct->cbSize)
{
case sizeof(MYSTRUCT):
    // do something
    break;
case sizeof(MYSTRUCTEX):
    // do something else
    break;
default:
    bRet = FALSE; // unknown version. dude!
}
E ceva naspa? :D



User avatar
Silviu Ardelean
Senior
Senior
Posts: 1175
Joined: 12 Jul 2007, 09:22
Judet: Timiş
Location: Timisoara
Contact:

Re: cod naspa

Post by Silviu Ardelean » 18 Feb 2010, 02:03

Da. Mi se pare o mare aberatie! :thumbdown: Mai lipsea un sizeof() ca parametru la switch() si exemplu era candidat perfect la tiplul de "cele mai naspa cod".

Iar daca dimensiunile a doua structuri ar fi egale, atunci individul ce a scris aceasta "opera" a mai pus-o de mamaliga. Sa se mire de ce nu intra pe unul din aceste cazuri. :tease:

User avatar
cristianamarie
Membru++
Membru++
Posts: 480
Joined: 12 Mar 2009, 18:47
Judet: Iaşi
Location: Iasi

Re: cod naspa

Post by cristianamarie » 18 Feb 2010, 10:44

Din pacate, nu e. Poti avea ceva gen

Code: Select all

struct S_V1 {
  ... // variabile size S_V1
};
struct S_V2 {
  ... // variabile size S_V2
};

struct S_V { // public
  DWORD cbSize;
  LPBYTE pData; // S_V1* sau S_V2* ?
};
...
struct S_V sv1 = { sizeof(S_V1), NULL }; // on output, will contain a S_V1*
struct S_V sv2 = { sizeof(S_V2), NULL }; // on output, will contain a S_V2*

BOOL GetSV(struct S_V* psv) {
  if(psv != NULL) {
    switch(psv->cbSize) {
      case sizeof(S_V1):
        psv->pData = (LPVOID)HeapAlloc(GetProcessHeap(), 0, sizeof(S_V1));
        memcpy(psv->pData, buffer_of_type_S_V1, sizeof(S_V1));
        return TRUE;

      case sizeof(S_V2):
        psv->pData = (LPVOID)HeapAlloc(GetProcessHeap(), 0, sizeof(S_V2));
        memcpy(psv->pData, buffer_of_type_S_V2, sizeof(S_V2));
        return TRUE;

      default:
        SetLastError(ERROR_INCORRECT_SIZE);
        return FALSE;
    }
  }
}
Functiile NetAPI toate sint cu LPBYTE* ca output arg. Unul cere WKSTA_INFO_100, altul WKSTA_INFO_101, altul WKSTA_INFO_102.
Nu zic ca e bine ca au fost scrise asa (desi cind ai de-a face cu N provideri de output data, singura cale e LPBYTE*...) ci pot exista cazuri legacy unde pot aparea decizii in functie de size.
Nuclear launch detected

User avatar
Silviu Ardelean
Senior
Senior
Posts: 1175
Joined: 12 Jul 2007, 09:22
Judet: Timiş
Location: Timisoara
Contact:

Re: cod naspa

Post by Silviu Ardelean » 18 Feb 2010, 10:55

De acord. Numai ca trebuie sa ai mari griji la dimensiunile structurilor (a.i. sa fie unice) cand iei decizia sa scrii o astfel de functie.
Nu cred ca e un exemplu de cum se scrie cod. Mai degraba, un contra-exemplu.

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3776
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: cod naspa

Post by Ovidiu Cucu » 18 Feb 2010, 14:16

In primul rand trebuie sa fim intelegatori, pentru ca Windows API(nterface) este C si deci nu are la dispozitie inheritance, polymorphism, templates, RTTI si alte mijloace care ar oferi solutii mai elegante.

Deci, pe de o parte pentru a pastra numarul de functii intr-o limita rezonabila (si-asa sunt jdemii), pe de alta parte pentru a avea o compatibilitate intre versiuni (asa cum a punctat deja Cristi), se recurge la asemenea solutii, printre care parametri care pointeaza la date de tip diferit in functie de un altul, precum si acel "enervant" struct_type::cbSize care musai trebuie umplut cu size-ul structurii, aparent "nashpa" si fara sens si care care ar putea induce cosmaruri unui arhitect care doarme cu "Mastering UML" si "GoF" sub cap. :)

User avatar
Silviu Ardelean
Senior
Senior
Posts: 1175
Joined: 12 Jul 2007, 09:22
Judet: Timiş
Location: Timisoara
Contact:

Re: cod naspa

Post by Silviu Ardelean » 26 Jan 2011, 17:23

Iertati-ma, dar nu ma pot abtine:

Code: Select all

 for(int i=0;i<4;i++)
       memcpy(bmp2+i*3*sizeof(int),&(*bmp1[i]),3);

Dragos Cojocari
Membru++
Membru++
Posts: 789
Joined: 11 Jul 2007, 14:11

Re: cod naspa

Post by Dragos Cojocari » 26 Jan 2011, 20:00

Silviu Ardelean wrote:Iar daca dimensiunile a doua structuri ar fi egale, atunci individul ce a scris aceasta "opera" a mai pus-o de mamaliga. Sa se mire de ce nu intra pe unul din aceste cazuri. :tease:
Problema asta e prinsa la compilare. Daca ai 2 structuri cu aceasi dimensiune nu poti utlizia aceasta metoda deloc.

User avatar
Silviu Ardelean
Senior
Senior
Posts: 1175
Joined: 12 Jul 2007, 09:22
Judet: Timiş
Location: Timisoara
Contact:

Re: cod naspa

Post by Silviu Ardelean » 26 Jan 2011, 20:23

Dragos Cojocari wrote:Problema asta e prinsa la compilare. Daca ai 2 structuri cu aceasi dimensiune nu poti utlizia aceasta metoda deloc.
Right. Oricum, sa pui sizeof() la case mi se pare un bad practice ce poate, in timp, sa genereze batai de cap.

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3776
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: cod naspa

Post by Ovidiu Cucu » 26 Jan 2011, 23:16

Silviu Ardelean wrote:Iertati-ma, dar nu ma pot abtine:

Code: Select all

 for(int i=0;i<4;i++)
       memcpy(bmp2+i*3*sizeof(int),&(*bmp1[i]),3);
Poti detalia problema?

User avatar
zlatomir
Membru++
Membru++
Posts: 282
Joined: 04 Jul 2009, 23:59
Location: Arad
Contact:

Re: cod naspa

Post by zlatomir » 26 Jan 2011, 23:39

Acel 3*** e problema principala (si cauza pt care codul functioneaza pt char dar nu pt int)

LE*** al treilea parametru al memcpy

User avatar
Silviu Ardelean
Senior
Senior
Posts: 1175
Joined: 12 Jul 2007, 09:22
Judet: Timiş
Location: Timisoara
Contact:

Re: cod naspa

Post by Silviu Ardelean » 27 Jan 2011, 00:08

Ovidiu Cucu wrote:
Silviu Ardelean wrote:Iertati-ma, dar nu ma pot abtine:

Code: Select all

 for(int i=0;i<4;i++)
       memcpy(bmp2+i*3*sizeof(int),&(*bmp1[i]),3);
Poti detalia problema?
Sa nu uitam titlul topicului. Aici nu vorbim neapat de cod eronat... cat despre cod scris naspa.
Exemplul de unde l-am copiat... era gresit abordat, chiar si gresit scris. Sa fiu sincer... nu am vazut pana acum asa ceva.

Daca tot vorbim de copieri de buffere din imagine, o abordare normala ( 1D - mult discutata azi) ar fi ceva de genul:

Code: Select all

memcpy(pImgBufDest,pImgBufSrc, nSizeY*nSizeX*sizeof(TYPE)); // aici am putea vorbi de notiunea de pitch ptr nSizeX dar nu face subiectul topicului

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3776
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: cod naspa

Post by Ovidiu Cucu » 27 Jan 2011, 11:31

Silviu Ardelean wrote:
Dragos Cojocari wrote:Problema asta e prinsa la compilare. Daca ai 2 structuri cu aceasi dimensiune nu poti utlizia aceasta metoda deloc.
Right. Oricum, sa pui sizeof() la case mi se pare un bad practice ce poate, in timp, sa genereze batai de cap.
Ok, sa zicem ca "sa pui sizeof() la case e bad practice".
Ne conformam si ne apucam voniceste de scris:

Code: Select all

   if(pMyStruct->cbSize == sizeof(MYSTRUCT))
   {
      // do something
   }
   else if(pMyStruct->cbSize == sizeof(MYSTRUCTEX))
   {
      // do something else
   }
   else
   {
      bRet = FALSE; // unknown version. dude!
   }
Tinand cont si de ce-a spus Dragos, care-i mai nashpa?
Unde-i mai bine de gasit o tampenie, sa-i zicem de "design"? La compilare, sau dupa ce clientul a dat cu masina-n stalp? (o putem intreba si pe Madam Misra :D).

Despre fenta cu cbSize, des intalnita in Windows API.
Mi se pare o solutie Ok din toate punctele de vedere. Ar fi fost mai inginereste sa avem (pornesc de la postul lui Cristi) NetWkstaGetInfo100, NetWkstaGetInfo101, NetWkstaGetInfo102, etc in loc de o singura functie NetWkstaGetInfo?
Eu nu cred.
Si asta inca nu-i fi nimic, sunt altele si mai si.

Din nou: Windows API este o biblioteca C (non-C++, non-Java, non-GoF,..., C-chior, zi cum vrei).
In C++ or fi alte soluti mai bengo dar in C ne descurcam cu ce avem.

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3776
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: cod naspa

Post by Ovidiu Cucu » 27 Jan 2011, 11:49

Silviu Ardelean wrote:Exemplul de unde l-am copiat... era gresit abordat, chiar si gresit scris. Sa fiu sincer... nu am vazut pana acum asa ceva.
"Cine nu munceste, nu greseste".
QUIZ: Cine nu greseste? :)
Ok, am vazut, de-acuma stim, mergem mai departe...

User avatar
Silviu Ardelean
Senior
Senior
Posts: 1175
Joined: 12 Jul 2007, 09:22
Judet: Timiş
Location: Timisoara
Contact:

Re: cod naspa

Post by Silviu Ardelean » 31 Jan 2011, 15:09

Ovidiu Cucu wrote:Ok, sa zicem ca "sa pui sizeof() la case e bad practice".
Ne conformam si ne apucam voniceste de scris:

Code: Select all

   if(pMyStruct->cbSize == sizeof(MYSTRUCT))
   {
      // do something
   }
   else if(pMyStruct->cbSize == sizeof(MYSTRUCTEX))
   {
      // do something else
   }
   else
   {
      bRet = FALSE; // unknown version. dude!
   }
Tinand cont si de ce-a spus Dragos, care-i mai nashpa?
Unde-i mai bine de gasit o tampenie, sa-i zicem de "design"? La compilare, sau dupa ce clientul a dat cu masina-n stalp? (o putem intreba si pe Madam Misra :D).
Point taken (clar ca la compilare)! :thumbup:

User avatar
Silviu Ardelean
Senior
Senior
Posts: 1175
Joined: 12 Jul 2007, 09:22
Judet: Timiş
Location: Timisoara
Contact:

Re: cod naspa

Post by Silviu Ardelean » 15 Apr 2011, 10:10

Enjoy: http://www.viva64.com/en/b/0094/ :)
Interesanta si adevarata concluzia autorului: There is one conclusion as always: he who makes no mistakes, makes nothing. No developer, even a skillful one, is secure from even silliest errors. Totusi, nu scuza perlele...

Post Reply