2015-12-13 12 views
6

Ho definito alcune funzioni e stampare il loro indirizzo come questo:C++ puntatore a funzione non è cambiato

#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); 
} 

Quando stampo il nome della funzione (indirizzo) che tutti Stampa 1 sul mio compilatore (Mingw gcc 4.8) .

OK o dovrebbe essere diverso?

risposta

0

You' Non stampare l'indirizzo perché è ora convertito in un valore booleano.

Ma si può fare ad es. questo:

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

Ora si otterrà l'indirizzo effettivo.

+0

Supponendo che la dimensione di un puntatore a funzione non sia maggiore della dimensione di 'unsigned long long int'. Dovresti anche aggiungere 'const' al cast per prevenire incidenti. –

+1

Sì, beh ... in C++ 11 lungo è almeno 64 bit. – juzzlin

+0

Quindi? Cosa succede se i puntatori sono 128 bit in futuro? Una volta erano solo a 16 bit. –

3

Non esiste un sovraccarico di operator<< per std::ostream che accetta un puntatore a funzione. Pertanto è preferibile il sovraccarico operator<<(std::ostream&, bool). L'indirizzo di una funzione viene sempre valutato su true quando convertito in bool. Quindi, 1 è stampato.

in alternanza, se un puntatore a funzione non è più grande della dimensione di un puntatore di dati, potresti lanciare il puntatore funzione a una void* tramite reinterpret_cast e evocano il operator<<(std::ostream&, void*) di sovraccarico e quindi ottenere l'indirizzo effettivo della funzione di stampa.

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

Live Demo

Tuttavia, come correttamente Neil e M.M menzionati nelle osservazioni non c'è alcuna conversione standard da un puntatore a funzione a un puntatore di dati, e questo potrebbe evocare un comportamento indefinito.

In alternativa, e, a mio modesto parere correttamente, si potrebbe formattare il puntatore a funzione come un buffer gamma char e convertire il suo indirizzo in una stringa nel seguente modo:

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

Supponendo che la dimensione di un puntatore a funzione non sia maggiore della dimensione di un puntatore di dati. Dovresti anche aggiungere 'const' al cast per prevenire incidenti. –

+0

@NeilKirk Questo è corretto. – 101010

+0

nota: questa conversione in 'void *' non è richiesta per esistere –