为什么一个函数期望引用能用指针工作?

问题描述 投票:2回答:1

我正在用C++写一个程序,使用一个C库。这个库采取指向函数的指针进行回调,我希望它能调用实例方法。幸运的是,这个库采取了一个额外的数据参数,这个参数只是一个 "void *",并且没有变化地传递给回调。所以,我创建了一个通用的回调包装函数。

void callbackWrapper(std::function<void ()> &func) {
    func();
}

现在,当我需要在库中注册一个回调时,我传递一个指向callbackWrapper函数的指针作为要调用的函数,以及一个指向std::function的指针作为额外的数据参数。当回调发生时,它会调用我的包装器,然后调用我真正想调用的方法lambdaw。

但是,上面的代码有一个错误。我使用了"&",而不是 "*",这意味着函数期望的是一个 参考 到一个std::函数,而不是一个指针。函数 已经被这样定义了。

void callbackWrapper(std::function<void ()> *func) {
    (*func)();
}

我很久以来都没有注意到这个错误... 因为它工作得很完美。我之所以注意到,是因为我在追踪一个不相关的bug时,刚好看到了它。所以,我的问题是,为什么?我有三个可能的答案。

  1. C++标准允许在这种情况下自动将指针提升为引用。
  2. 我的编译器(gcc 9.3.1)注意到了这个不匹配,并默默地帮我修复了它。
  3. 指针的地址刚好落在堆栈框架的正确位置,调用可以成功。

我的理论是否正确?如果不对,发生了什么?

c++ c gcc shared-libraries
1个回答
1
投票

对于你的例子,很可能情况3是真的。

把引用当作指针来传递是非常明智的,大多数ABI可能都会这样做。

例如,Itanium C++ ABI (例如,这是Linuxx64上使用的ABI)。

引用参数通过传递一个指向与引用绑定的对象的指针来处理。

© www.soinside.com 2019 - 2024. All rights reserved.