Aveți nevoie de macrocomenzi

Macro-ul este cel mai neplăcut instrument al lui C și C ++, un vârcolac care se ascunde sub masca funcției, o pisică care merge singură și nu acordă nici o atenție limitelor domeniului tău. Feriți-vă de ea!







discuție

Este greu să găsești o limbă suficient de colorată pentru a exprima tot ce vrei să spui despre macrocomenzi. Dar, totuși, oferim câteva citate.

Macrouri din multe motive - un lucru foarte neplăcut, care poate deveni pur și simplu periculos. Mai întâi de toate, acest lucru se datorează faptului că macrocomenzile sunt un mijloc de înlocuire a textului, care acționează în timpul procesării textului sursă de către un preprocesor, adică chiar înainte de începerea oricărei verificări a sintaxei și a semanticii.

Nu-mi plac cele mai multe tipuri de preprocesoare și macro-uri. Unul dintre obiectivele C ++ - face redundant C Preprocessor (§4.4, §18), pentru că eu cred că este o mare greșeală.

Macrogramele nu sunt aproape niciodată necesare în C ++. Utilizați const (§5.4) sau enum (§4.8) pentru a defini constantele explicite [cf. Recomandarea 15], în linie (§7.1.1) pentru a evita overhead unui apel de funcție [dar vezi. Recomandarea 8], șablon (Capitolul 13) pentru determinarea familiilor de funcții și tipuri [vezi. recomandările de la 64 la 67] și spațiul de nume (§8.2) pentru a evita conflictele de nume

Prima regulă pentru utilizarea macrocomenzilor este: nu le utilizați până când nu aveți altă ieșire. Practic, orice macro indică o imperfecțiune a limbajului de programare, a programului sau a programatorului.

Principala problemă cu macrocomenzile C ++ este că ele arată mult mai atractive decât sunt de fapt. Macrorele ignoră domenii, ignoră alte caracteristici și reguli de limbă și înlocuiesc toate caracterele care sunt redefinite cu directiva #define. până la sfârșitul dosarului. Utilizarea macrocomenzilor arată ca un apel sau o funcție, dar nu are nimic de-a face cu ei. Macrocomenzi „neigienice“, în sensul că acestea pot fi deschise brusc, iar rândul său, în funcție de contextul utilizării lor într-o varietate de modele. Înlocuirea textului, realizată prin macrocomenzi, face să scrie cel puțin un mic grad de macro "decent", cu un amestec de artă și magie neagră.

Programatorii care cred că cel mai greu mod de a descifra erorile legate de șabloane este, probabil, pur și simplu să nu se ocupe niciodată de macrocomenzile prost prost scrise sau abuzate. Șabloanele fac parte din sistemul de tip C ++ și permit astfel compilatorului să facă mult mai bine cu ei decât cu macro-uri care nu au prea multe de-a face cu limbajul de programare. Mai rău, spre deosebire de modele, macrocomenzile invalide pot fi expuse la ceva care, din pricină pură, va compila, fără nici un sens. În cele din urmă, eroarea în macro este detectată numai după ce macro-ul este extins, nu când este detectat.

Chiar și în acele cazuri rare în care utilizarea de macro-uri este justificată (a se vedea. Subsecțiunea privind excepțiile), nu se poate gândi chiar cu privire la modul de a scrie un macro, care este un cuvânt comun sau o abreviere. Pentru toate macrocomenzile, utilizați directiva #undef cât mai curând posibil. întotdeauna oferindu-le nume urât neobișnuit, cu majuscule, evitând în același timp plasarea lor în fișierele antet.







Un exemplu. Treceți instanțiația șablonului la macro. Macrorele înțeleg suficient numai paranteze rotunde și pătrate. În C ++, cu toate acestea, este utilizată o nouă construcție cu paranteze unghiulare, utilizată în șabloane. Macroanele nu pot rezolva corect această situație, deci apelarea

macro-ul percepe ca și cum ar fi fost transmise două argumente, adică Foo. în timp ce în realitate acest construct reprezintă un singur obiect C ++.

excepții

Macro-urile sunt singura soluție posibilă pentru anumite sarcini importante, cum ar fi protecția directivei #include (a se vedea alin. 24, recomandare), utilizați # ifdef și #if directivele definite pentru compilarea și punerea în aplicare a assert condiționate (a se vedea. Recomandarea 68).

Când compilați condițional (de exemplu, piese dependente de sistem), evitați răspândirea directivelor #ifdef pe tot textul. In schimb, cel mai bun mod de a organiza codul, astfel încât utilizarea macro oferă posibilitatea de implementări alternative ale unei interfețe comune, care vor fi apoi utilizate în program.

Este posibil (dar cu precauție) să utilizați macrocomenzi în loc de un număr mare de copii și inserții de fragmente de cod închis.

17. Evitați numerele magice

Evitați utilizarea constantelor literale în cod ca 42 sau 3.1415926. Astfel de constante nu sunt explicative și complică menținerea codului, deoarece introduc în el un tip de duplicare greu de determinat. Utilizați nume și expresii simbolice, cum ar fi lățimea * aspectRati.

discuție

Numele adaugă informații și introdu un singur punct de escortă; În schimb, duplicate pe tot parcursul programului, numerele obișnuite sunt anonime și dificil de întreținut. Constantele trebuie să fie enumerări sau const-valori, cu domeniul și numele corespunzătoare.

Un număr 42 nu poate fi același număr 42. ambele. Pentru a face lucrurile si mai rele, un programator poate efectua orice calcul „în mintea“ (de exemplu: „Aceasta este de 84 - doar dubla 42, care a fost de cinci rânduri de mai sus“), care confundă complet codul și face înlocuirea ulterioară a 42 sursă constantă diferită a unui număr foarte mare de erori .

Exemplul 1. Constante importante din domeniu la nivelul spațiilor de nume.

Exemplul 2. Constante specifice unei clase date. Puteți defini constante integrale statice în definiția clasei; constantele de alte tipuri necesită o definiție separată sau aplicarea unor funcții scurte.

18. Declarați variabilele cât mai local posibil

Evitați "umflarea" domeniilor. Variabilele ar trebui să fie cât mai mici posibil și durata lor de viață ar trebui să fie cât mai scurtă posibil. Această recomandare este de fapt un caz special al recomandării 10.

discuție

Variabilele a căror durată de viață depășește cele necesare necesită o serie de dezavantaje.

Ele fac programul greu de înțeles și urmat. De exemplu, în cazul în care codul actualizează linia de cale la nivel de modul, dacă se modifică numai discul curent?

Ei înfundă contextul cu numele lor. Consecința imediată este că variabilele la nivelul spațiului de nume, cele mai vizibile în rândul celorlalte, sunt, de asemenea, cele mai grave în același timp (a se vedea recomandarea 10).

Ele nu pot fi întotdeauna inițializate corect. Nu declarați niciodată o variabilă înainte de ao putea inițializa corect. variabile neinițializate - sursa de „trântit“ erori în toate programele C și C ++, și necesită o atenție deosebită datorită faptului că acestea nu pot fi întotdeauna detectate de către compilator (a se vedea recomandarea 19.).

În special, versiunile vechi ale lui C au cerut ca variabilele să fie definite numai la începutul domeniului de aplicare; un astfel de stil în C ++ este în uz. O problemă serioasă cu această limitare este că acesta este de multe ori la începutul domeniului de aplicare nu există suficiente informații pentru a inițializa variabile. Ca rezultat, ai rămas cu două opțiuni - fie pentru a inițializa variabile la o anumită valoare prestabilită (de exemplu, zero), care este de obicei risipitoare și poate duce la erori (dacă se utilizează o variabilă înainte de a va deveni o valoare semnificativă) sau lăsați-le neatribuit că periculoase. O variabilă neinitializată a unui tip definit de utilizator va fi autoinalizată cu o anumită valoare goală.

Tratamentul acestei boli este foarte simplu - definiți fiecare variabilă pe plan local, după cum puteți, ceea ce înseamnă de obicei un punct imediat înainte de prima utilizare, când aveți suficiente date pentru inițierea corectă.

excepții

Uneori, din punct de vedere al productivității, ar putea fi avantajos să se ia o variabilă în afara buclei (a se vedea recomandarea 9).

Deoarece constantele nu fac parte din statul programului, această recomandare nu se aplică acestora (a se vedea recomandarea 17).







Articole similare

Trimiteți-le prietenilor: