【问题标题】:c++ pointer to function not changedc++指向函数的指针没有改变
【发布时间】:2015-12-13 19:51:56
【问题描述】:

我已经定义了一些函数,并像这样打印它们的地址:

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

当我打印函数的名称(地址)时,它们都会在我的编译器(Mingw gcc 4.8)上打印1

可以还是应该有所不同?

【问题讨论】:

    标签: c++ function pointers


    【解决方案1】:

    对于采用函数指针的std::ostream,不存在operator&lt;&lt; 的重载。因此operator&lt;&lt;(std::ostream&amp;, bool) 重载是首选。当转换为bool 时,函数的地址总是被评估为true。因此,打印 1。

    或者,如果函数指针不大于数据指针的大小,您可以通过reinterpret_cast 将函数指针转换为void* 并引发operator&lt;&lt;(std::ostream&amp;, void*) 重载,从而获得实际地址打印功能。

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

    Live Demo

    但是,正如 Neil 和 M.M 在 cmets 中正确提到的那样,没有从函数指针到数据指针的标准转换,这可能会引发未定义的行为。

    或者,按照我的拙见,您可以将函数指针格式化为char 数组缓冲区,并按以下方式将其地址转换为字符串:

    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

    【讨论】:

    • 假设函数指针的大小不大于数据指针的大小。您还应该在演员表中添加const 以防止发生意外。
    • 注意:到void *的转换不需要存在
    • @M.M 我知道,提到了 UB 并提出了另一种更安全的方法。
    • @NeilKirk,提到了 UB 并提出了另一种更安全的方法。
    【解决方案2】:

    您没有打印地址,因为它现在已转换为布尔值。

    但是你可以做例如这个:

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

    现在您将获得实际地址。

    【讨论】:

    • 假设函数指针的大小不大于unsigned long long int的大小。您还应该将const 添加到演员表中以防止发生意外。
    • 是的,嗯...在 C++11 中 long long 至少是 64 位。
    • 所以?如果将来指针是 128 位的呢?曾经它们只有 16 位。
    • 这可能会导致对齐冲突,如果它甚至存在的话..没有理由使用除void *之外的任何指针类型。
    • 对不起我的错误..我没有发现 *
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-17
    • 1970-01-01
    相关资源
    最近更新 更多