c++ - rand() 函数的动态链接器错误

标签 c++ linux c++11 dynamic-linking

我之前已经问过这方面的问题,但再次引用以下代码

#include <iostream>
using std::cout;
using std::endl;
#include <dlfcn.h>

int rand() throw() {

    // get the original rand() function
    static auto original_rand = (decltype(&rand)) dlsym(RTLD_NEXT, "rand");

    cout << "Call made to rand()" << endl;
    return original_rand();
}

为什么编译会出现如下错误

error: exception specification in declaration does not match previous declaration

为什么会这样?链接器如何知道这只是我自己声明的另一个 rand() 函数,而是 rand() 的现有版本?

最佳答案

您的一个头文件(在我的例子中为 <iostream>)默默地包含了 <stdlib.h> ,其中包含 rand() 功能。后者没有任何异常规范。在您的代码中,您尝试重载 rand() , 但签名与 <stdlib.h> 中的签名相同除了异常说明符(它不是函数类型的一部分,所以不能单独重载它),因此你会得到一个编译时错误(不是链接器错误,正如你在问题中提到的那样) .

如果你想知道为什么函数 rand()静默包含在全局命名空间中也是可见的(正如您所期望的那样,仅作为 std::rand 不可见),这是因为 C 库函数通常通过直接

导入到标准 C++ 头文件中
// <new_cpp_header>
#include <old_c_header.h> 

其次是

namespace std
{
    using old_function_from_old_c_header;
} 

因此该函数最终出现在全局命名空间和 namespace std; 中.在我看来,这不是一个很好的做法,但现在大多数编译器都是这样做的。

例如,<cstdio>文件有:

// <cstdio>
#include <stdio.h>
namespace std
{
    using printf;
    // ...
}

所以都是printfstd::printf是可见的,即使您只包含 <cstdio> (而不是 <stdio.h> )。

关于c++ - rand() 函数的动态链接器错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35329990/

相关文章:

c++ - 序列化日期时间

c++ - 它在 VS 中不起作用,但在我运行它时它在 CLion 中起作用

linux - 使用 g++ 链接静态库而不是共享

c++ - 我对为 std::array 赋值的方式有一些疑问

linux - 为什么我必须使用 libtool --mode==execute gdb wireshark 才能调试 wireshark

linux - 为什么在没有调用 Close() 或 Shutdown() 时发送 RST?

c++ - 模板元编程与经典名称重载相结合

c++ - std::vector 不接受我的结构作为模板

c++ - 带有 5 个参数的 WPARAM

c++ - 在 boost for_each 中运行成员函数 vector