[C++] preprocesor

piotru64
Użytkownik
Użytkownik
Posty: 45
Rejestracja: 29 paź 2009, o 20:27
Płeć: Mężczyzna
Podziękował: 6 razy
Pomógł: 3 razy

[C++] preprocesor

Post autor: piotru64 »

Mógłby mi ktoś rozpisać jak beda wyliczne wartości funkcji w poniższym kodzie:

Kod: Zaznacz cały

#define kwadrat(x) x*x
#define szescian(x) x*x*x
#define kwadrat2(x) x*x*x*x

main()
{
int a=0;
int b=0;
int c=0;
kwadrat(++a);
szescian(++b);
kwadrat2(++c);


int a=0;
int b=0;
int c=0;
kwadrat(a++);
szescian(b++);
kwadrat2(c++);

}

MichalProg
Użytkownik
Użytkownik
Posty: 410
Rejestracja: 28 cze 2011, o 21:11
Płeć: Mężczyzna
Lokalizacja: Łódź
Podziękował: 62 razy
Pomógł: 1 raz

[C++] preprocesor

Post autor: MichalProg »

Niestety, ale makra, w przeciwieństwie do funkcji, podstawiają, a w zasadzie wklejają całą frazę podaną w parametrze. Tzn. że:

Kod: Zaznacz cały

kwadrat(++a); // ++a*++a, czyli 1 * 2, lub 2 * 1 (w zależności od kompilatora)
Nie powinno się preinkrementować (++zmienna) ani postinkrementować (zmnienna++) w jednym wyrażeniu, gdyż wynik jest zależny od inkrementacji preprocesora. Np.

Kod: Zaznacz cały

int n = 1;
cout << n++ + ++n*n++;
Wartość takiego wyrażenia jest nieprzewidywalna (chyba, że wie się jak jest zaimplementowany używany kompilator)

PS. jeżeli chcesz mieć dobrze działający kod, napisz funkcję zamiast makra:

Kod: Zaznacz cały

int kwadrat(int a)
{
      return a * a;
}
piotru64
Użytkownik
Użytkownik
Posty: 45
Rejestracja: 29 paź 2009, o 20:27
Płeć: Mężczyzna
Podziękował: 6 razy
Pomógł: 3 razy

[C++] preprocesor

Post autor: piotru64 »

Kod: Zaznacz cały

kwadrat(++a); // ++a*++a, czyli 1 * 2, lub 2 * 1 (w zależności od kompilatora)
Nie wiem czy to tylko moj kompilator, ale własnie jest 2*2. kwadrat(++a) zwraca 4, ale juz szescian 2*2*3 nie wiem dlaczego robi mi ta 2 zamiast jedynki w pierwszej preinkrementacji.


Ciekawi mnie tom, bo miałem takie pytanie i jak sobie w domu sprawdziłem to sie troszke zdziwiłem
Afish
Moderator
Moderator
Posty: 2725
Rejestracja: 15 cze 2008, o 15:45
Płeć: Mężczyzna
Lokalizacja: Seattle, WA
Podziękował: 3 razy
Pomógł: 356 razy

[C++] preprocesor

Post autor: Afish »

Standard określa takie zachowanie jako niezdefiniowane i równie dobrze komputer mógłby zjeść Twojego kota, więc nie ma w tym nic zaskakującego. Z ciekawości można sprawdzić, co kompilator widzi po uruchomieniu preprocesora (przełączniki /E w VS lub -E w gcc), a potem zerknąć na wyprodukowany kod asemblera (lub zdeasemblować kod maszynowy).
ODPOWIEDZ