misza_88
(misza_88)
19 Luty 2015 20:10
#1
Hej,
może mi ktoś wytłumaczyć dlaczego kompilator wykonuje makro SWAP pomimo tego, iż warunek if nie jest spełniony?
#include <stdio.h>
#define SWAP(a,b) temp=a; a=b; b=temp;
struct IntPair {
int a;
int b;
};
int main(void) {
struct IntPair i = {20,10};
int temp = 0;
if (i.a < i.b)
SWAP(i.a,i.b);
printf("%d %d %d\n",i.a,i.b,temp);
return 0;
}
Pozdrawiam
adammo
(Adammo)
19 Luty 2015 21:16
#2
W twoim przypadku kompilator generuję taki kod (dodałem enter aby było to bardziej zrozumiałe):
if (i.a < i.b)
temp = i.a; // tylko ta linijka jest zależna od if
i.a = i.b;
i.b = temp;
;
Jeśli chcesz aby kod działał prawidłowo musisz SWAP umieścić w klamrach:
if (i.a < i.b){
SWAP(i.a,i.b)
}
Używanie makr to w zasadzie proszenie się o kuku: http://stackoverflow.com/questions/3982348/implement-generic-swap-macro-in-c tu masz rozkminę jak powinno to wyglądać - pytanie, czy warto?
W dodatku piszesz o C++, a jest to czyste C.
Świadczy o tym dodanie słowa kluczowego struct przed deklaracją zmiennej i.
nintyfan
(nintyfan)
21 Luty 2015 12:28
#5
W przypadku C++ możesz korzystać z szablonów funkcji - znacznie potężeniejszy mechanizm niż makra.
misza_88
(misza_88)
22 Luty 2015 11:30
#6
Dzięki wszystkim za odpowiedź. Wiem, że makra to zło - w technikum nauczyciel powiedział, że jest coś takiego ale lepiej tego nie używać bo są lepsze metody takie jak szablony funkcji, o których wspomniał nintyfan.
Zastanawiałem się tylko dlaczego po if wykonywana jest część SWAP, po rozpisaniu adammo wszystko stało się jasne.
Jeszcze raz dziękuję za wyjaśnienia!
Ryan
(Ryan)
22 Luty 2015 13:17
#7
Generalnie makra złożone z kilku instrukcji powinny być umieszczone wewnątrz do{/*…*/}while(0). To bezpieczne i powszechnie uznane rozwiązanie.