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.
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:
[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).