2015-12-13 23 views
6

Mam zdefiniowane niektóre funkcje i wydrukować swój adres tak:C++ wskaźnik nie działać zmieniła

#include<iostream> 
#include <string> 

using std::cout; 

std::string func() 
{ 
    return "hello world\n"; 

} 

int func2(int n) 
{ 
    if (n==0) 
    { 
     cout << func2 << std::endl; 
     return 1; 
    } 

    cout << func2 << std::endl; 

    return n + func2(n - 1); 
} 

//================================================ 
int main() 
{ 
    int (*fun)(int) = func2; 

    cout << fun; 

    cout << std::endl << func2(3); 
} 

Kiedy drukować nazwą funkcji (adres) wszystko drukują 1 na moim kompilatora (Mingw gcc 4.8) .

Czy wszystko jest w porządku?

Odpowiedz

0

you” nie drukuje adresu, ponieważ jest teraz konwertowany na wartość boolowską.

Ale możesz zrobić np. to:

std::cout << reinterpret_cast<unsigned long long int *>(func2) << std::endl; 

Teraz otrzymasz aktualny adres.

+0

Zakładając, że rozmiar wskaźnika funkcji nie jest większy niż rozmiar 'unsigned long long int'. Powinieneś również dodać "const" do obsady, aby zapobiec wypadkom. –

+1

Tak, cóż ... w C++ 11 long long ma co najmniej 64 bity. – juzzlin

+0

Tak? Co jeśli wskaźniki są 128-bitowe w przyszłości? Kiedyś mieli tylko 16 bitów. –

3

Nie istnieje przeciążenie operator<< dla std::ostream, które ma wskaźnik funkcji. W związku z tym preferowane jest przeciążenie operator<<(std::ostream&, bool). Adres funkcji zawsze jest oceniany na true po przekonwertowaniu na bool. W ten sposób drukowany jest 1.

Alternatevely, jeśli wskaźnik funkcja nie jest większy niż rozmiar wskaźnika danych, można oddać swój wskaźnik funkcji do void* poprzez reinterpret_cast i wywołać przeciążenie operator<<(std::ostream&, void*) a tym samym uzyskać rzeczywisty adres funkcji drukowanej.

int (*fun)(int) = func2; 
std::cout << reinterpret_cast<void*>(fun) << std::endl; 

Live Demo

Jednakże, jak słusznie Neil i m.cz. wspomniano w komentarzach nie ma standardowy konwersja z funkcją wskaźnika do wskaźnika danych, a to może wywołać niezdefiniowanej zachowanie.

Alternatywnie, i moim skromnym zdaniem prawidłowo, można sformatować wskaźnik funkcji jako bufor tablicy char i przekształcić swój adres, aby ciąg w następujący sposób:

unsigned char *p = reinterpret_cast<unsigned char*>(&func2); 
std::stringstream ss; 
ss << std::hex << std::setfill('0'); 
for(int i(sizeof(func2) - 1); i >= 0; --i) ss << std::setw(2) 
               << static_cast<unsigned int>(p[i]); 
std::cout << ss.str() << std::endl; 

Live Demo

+1

Zakładając, że rozmiar wskaźnika funkcji nie jest większy niż rozmiar wskaźnika danych. Powinieneś również dodać "const" do obsady, aby zapobiec wypadkom. –

+0

@NeilKirk To prawda. – 101010

+0

Uwaga: ta konwersja do 'void *' nie musi istnieć –