#define SQR(x) (x*x) ?

Intrebari despre limbajul C++, standardul C++, STL, OOP in C++ sau alte subiecte nelegate de VisualC++
Post Reply
Abi_Moonbow
Junior
Junior
Posts: 15
Joined: 17 Apr 2013, 11:36
Judet: Argeş

#define SQR(x) (x*x) ?

Post by Abi_Moonbow » 02 May 2013, 00:20

Salutare!
Am citit si am dat peste urmatoarea linie de cod

#define SQR(x) (x*x)

ce face?


Va multumesc!



Viorel
Microsoft MVP
Microsoft MVP
Posts: 292
Joined: 13 Jul 2007, 12:26

Re: #define SQR(x) (x*x) ?

Post by Viorel » 02 May 2013, 09:22

Cred că este o macrodefiniție, care înlocuiește aparițiile de tipul SQR(ceva) cu ceva*ceva. De exemplu:

Code: Select all

y = SQR(7);
se înlocuiește cu

Code: Select all

y = 7 * 7;
obținînd astfel pătratul 49.

Funcționează altfel în cazul

Code: Select all

y = SQR(3+4);
care devine

Code: Select all

y = 3+4*3+4;
Rezultatul 19 nu mai este pătratul lui 3+4. Se poate corecta prin adăugarea parantezelor [http://tutorialsx.wordpress.com/category/tutoriale-c/]:

Code: Select all

#define SQR(x) ((x)*(x))
În practica modernă se preferă funcțiile inline:

Code: Select all

inline int SQR(int x) { return x * x; }
și generice:

Code: Select all

template< typename T >
inline T SQR(T x) { return x * x; }

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

Re: #define SQR(x) (x*x) ?

Post by Ovidiu Cucu » 02 May 2013, 10:04

Incerc si eu sa completez ceea ce deja a spus Viorel.

Este vorba despre o definitie preprocesor, macro-definitie sau pe scurt, un macro.
Ce face? Nu face nimic. :)
De facut face compilatorul in faza de preprocesare. Vezi aici despre fazele compilarii unui program: viewtopic.php?f=13&t=2417#p15556 , in care, printre altele, se "expandeaza" macro-urile.
Daca, scris la la modul general, avem definit un macro cu parametri, de forma
#define nume_macro(pf1, pf2,... pfN) token_string
la preprocesare, compilatorul inlocuieste toate nume_macro de dupa definitie cu token_string iar in cadrul acestuia, substituie parametrii formali (pf1... pfN) cu parametri actuali.

Exemplu:

Code: Select all

#define BABA_SAFTA(x,y) x + MOS_VASILE + y

   // ...
   int MOS_VASILE;
   int a;
   // ...
   int i = BABA_SAFTA(666, a);
Dupa preprocesare, codul de mai sus ar arata asa:

Code: Select all

   int MOS_VASILE;
   int a;
   // ...
   int i = 666 + MOS_VASILE + a;
In exemplul tau, nume_macro este SQR, token_string este (x*x) si avem un parametru formal x.
Conform celor spuse mai sus, daca avem de exemplu dupa definita data

Code: Select all

   int k = SQR(666);
dupa preprocesare vom avea

Code: Select all

   int k = (666*666);
Asta in principiu si discutand pe exemplul dat.
Mai sunt unele lucruri de discutat depre macro-definitii. Viorel a amintit deja de posibile "side effects" pentru care trebuie multa atentie atunci cand definesti un macro. De asemenea a spus ca in multe cazuri, in C++ se prefera functii inline sau template in locul macro-urilor cu argumente. Si mai sunt...
Insa cred ca astea pot fi subiectul unui alt topic.
Doar o remarca: nu ai spus concret unde ai vazut definitia. Se poate banui ca ori e vorba de o problema de interviu ori de cod scris de vreun programator "glumet" care vrea sa induca in eroare cetitorul cu un macro (cu acel nume, SQR, care sugereaza altceva decat ce se obtine dupa expandare).

Ca sa dau un alt exemplu.

Code: Select all

#define sizeof(x) rand()
Asta poate baga in balarii un intreg program si este greu de depistat ca bug.
In lumea reala a programarii, autorii glumelor de acest gen ar trebui impuscati. :D

neagu_laurentiu
Membru++
Membru++
Posts: 919
Joined: 23 Jul 2007, 11:32

Re: #define SQR(x) (x*x) ?

Post by neagu_laurentiu » 02 May 2013, 11:18

Ovidiu Cucu wrote:autorii glumelor de acest gen ar trebui impuscati. :D
Pai si cei din Catedrala Neamului se vor supara de exemplul tau cu baba & 666 :twisted:

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

Re: #define SQR(x) (x*x) ?

Post by Ovidiu Cucu » 02 May 2013, 17:03

[ off-topic ]
neagu_laurentiu wrote:
Ovidiu Cucu wrote:autorii glumelor de acest gen ar trebui impuscati. :D
Pai si cei din Catedrala Neamului se vor supara de exemplul tau cu baba & 666 :twisted:
Ai dreptate. Pacat, mare pacat, maica! Promit ca nu mai fac. :)

Abi_Moonbow
Junior
Junior
Posts: 15
Joined: 17 Apr 2013, 11:36
Judet: Argeş

Re: #define SQR(x) (x*x) ?

Post by Abi_Moonbow » 02 May 2013, 22:20

Va multumesc din nou pentru clarificare! Am inteles ce face si acum imi este destul de clar lucrul cu macro; m-am mirat totusi ca pot defini cu #define definitii mai complexe decat simplele constante... Cred insa ca pe viitor voi folosi functiile inline sau template.
Cat despre unde am gasit-o, a fost intr-un program si am avut mare noroc ca nu a folosit bug-ul amintit de Ovidiu Cucu... m-ar fi bagat rau de tot in ceata... :))

Cu mult respect,
Abi

viorel2005
Membru
Membru
Posts: 208
Joined: 24 May 2008, 09:41

Re: #define SQR(x) (x*x) ?

Post by viorel2005 » 03 May 2013, 22:08

Totusi, uneori macro-urile sunt foarte bune.
Sa presupunem ca doresti sa portezi un program Windows scris cu MFC in Linux folosind libraria GTK care e scrisa in C.
Programul Windows foloseste alte librarii care se compileaza pe Linux, ele fiind cross-platform.
Cel mai simplu lucru este sa comentezi codul din functiile problema:

Code: Select all

.....
#define OK 0
int WindowsFunction()
{
.....
//cod Windows
#if OK

#endif

return 0;
}

}

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

Re: #define SQR(x) (x*x) ?

Post by Ovidiu Cucu » 04 May 2013, 09:01

Cele de mai sus sunt doar recomandari referitoare la macro-urile cu argumente.
Macro-urile (incluzand cele cu argumente) sunt intotdeauna bune, daca sunt bine scrise si folosite acolo unde trebuie.
In primul rand, multe biblioteci/API-uri au interfata C. In C nu exista template si nici functii inline asa ca in asemenea biblioteci sunt pline de macro-uri.
Chiar si in cod C++, macro-urile cu argumente sunt uneori de neinlocuit sau ofera o solutie mai simpla versus functii template sau inline.

Post Reply