带有 rand() 函数的动态链接器错误

dynamic linker error with rand() function

本文关键字:动态 链接 错误 函数 rand 带有      更新时间:2023-10-16

我之前已经问过一个关于这个问题的问题,但再次参考以下代码

#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;中结束。这不是一个很好的做法 IMO,但这就是当今大多数编译器的做法。

例如,<cstdio>文件具有:

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

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