dla niewiernego @n0name_l:
inline double funkcja(double& x)
{
x = x*x;
double h1 = (1.0 - x);
double h2 = (1.0 + x);
return h1/h2;
}
int main()
{
double x=5;
double z = funkcja(x); //jakby to wyglądało po kompilacji?
}
kompilacja pod Visual Studio 2012 (z /Ox
):
00241000 push ebp
00241001 mov ebp,esp
00241003 and esp,0FFFFFFF8h
00241006 xor eax,eax
00241008 mov esp,ebp
0024100A pop ebp
0024100B ret
jest to tylko ramka stosu i return 0
. poza tym cała funkcja i zmienne wyleciały jako nie mające żadnego znaczenia.
ale wyświetlmy wynik:
...
#include <iostream>
int main()
{
double x=5;
double z = funkcja(x); //jakby to wyglądało po kompilacji?
std::cout << z;
}
teraz już kod ma wpływ na losy wszechświata, więc musi się wykonać.
01241220 push ebp
01241221 mov ebp,esp
01241223 and esp,0FFFFFFC0h
01241226 movsd xmm0,mmword ptr ds:[1243228h]
0124122E mov ecx,dword ptr ds:[1243030h]
01241234 sub esp,8
01241237 movsd mmword ptr [esp],xmm0
0124123C call dword ptr ds:[1243038h]
01241242 xor eax,eax
01241244 mov esp,ebp
01241246 pop ebp
01241247 ret
hmm, trochę to zagmatwane. jest ramka stosu, jakieś operacje na SSE, i skok do funkcji.
ale jeśli się przyjrzeć, to jest to w zasadzie tylko odczyt wartości z pamięci (movsd, mov).
czyżby więc?
#include <iostream>
int main()
{
std::cout << -24.0/26.0;
}
00EC1220 movsd xmm0,mmword ptr ds:[0EC3228h]
00EC1228 mov ecx,dword ptr ds:[0EC3030h]
00EC122E sub esp,8
00EC1231 movsd mmword ptr [esp],xmm0
00EC1236 call dword ptr ds:[0EC3038h]
00EC123C xor eax,eax
00EC123E ret
Ha! nagle nam zniknęła ramka stosu, ale istotne instrukcje są praktycznie takie same, tylko adresy się zmieniły.
więc TAK, kompilator zamienił całą funkcję, całe to double h2 = (1.0 + x);
itd. na banalne wyświetlenie gotowej wartości.