Strona 1 z 1

[C++] preprocesor

: 22 maja 2015, o 22:18
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++);

}


[C++] preprocesor

: 22 maja 2015, o 23:19
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;
}

[C++] preprocesor

: 24 maja 2015, o 12:22
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

[C++] preprocesor

: 24 maja 2015, o 19:31
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).