Dajmy na to, że masz funkcję
pow:
Kod: Zaznacz cały
double pow ( double base, double exponent );
long double pow ( long double base, long double exponent );
float pow ( float base, float exponent );
double pow ( double base, int exponent );
long double pow ( long double base, int exponent );
I teraz masz kod:
W tym momencie każda funkcja jest odpowiednia - nie ma bardziej odpowiedniej lub mniej odpowiedniej funkcji w tym wypadku (jeśli chodzi o typ zwracany), bo nastąpi niejawne rzutowanie. Kolejny kod:
Kod: Zaznacz cały
#include <cstdio>
void f(float)
{
printf("float\n");
}
void f(double)
{
printf("double\n");
}
void f(int)
{
printf("int\n");
}
void f(char)
{
printf("char\n");
}
int main()
{
f(65.0f);
f(65.0);
f(65);
f('A');
return 0;
}
Teraz kompilator w
trakcie kompilacji ma jakieś informacje co do typu argumentu i może je odpowiednio wykorzystać (zwróć uwagę, że 'A' ma taką samą wartość - 65 - jak pozostałe przykłady). W poprzednim przypadku wartość zwracana jest obliczana w
czasie wykonywania programu, więc kompilator nie wie czy zostanie zwrócona wartość 65 (potraktuje jako int), czy 65.5 (potraktuje jako double), czy 65.0 (niby to samo co 65, ale inny zapis binarny ze wzlgędu na typ). Funkcja po prostu zwraca określoną wartość o długości słowa (32 bity dla IA-32 (czy też raczej dwusłowa jak to się przyjęło z x86)). Czy jest to wskaźnik, liczba całkowita czy zmiennoprzecinkowa zależy już tylko od tego jak Twój program ją zinterpretuje. To są metadane, które nie są zapisywane w pliku wykonywalnym - one są tylko dla kompilatora.
Oczywiście można by stosować zapis (lub różnych trików, np takich jak post wyżej, ale moim zdaniem jest to sztuką dla sztuki):
Kod: Zaznacz cały
(long double) pow(10, 3);
static_cast<long double> (pow(10, 3));
Ale najwidoczniej ludzie zajmujący się tworzeniem języka nie uznali tego za dobry pomysł.
teka321 pisze:A jeśli zwróci wynik to i tak zostanie zapisany nie wiadomo gdzie..
Wynik funkcji jest zwracany w rejestrze eax (chyba we wszystkich konwencjach wywoływania funkcji dla x86).