[C++] if i #define


(misza_88) #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) #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)
}

(kostek135) #3

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?


(enedil) #4

W dodatku piszesz o C++, a jest to czyste C.

Świadczy o tym dodanie słowa kluczowego struct przed deklaracją zmiennej i.


(nintyfan) #5

W przypadku C++ możesz korzystać z szablonów funkcji - znacznie potężeniejszy mechanizm niż makra.


(misza_88) #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) #7

Generalnie makra złożone z kilku instrukcji powinny być umieszczone wewnątrz do{/*…*/}while(0). To bezpieczne i powszechnie uznane rozwiązanie.