Skip to content
Advertisement

dynamic linker error with rand() function

I already asked a question about this before but with reference to the following code again

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

Why does compiling this result in the following error

error: exception specification in declaration does not match previous declaration

Why would this happen? How does the linker know that this is just another rand() function I have declared myself but rather an existing version of rand()?

Advertisement

Answer

One of your header files (<iostream> in my case) silently includes <stdlib.h>, which contains the rand() function. The latter does not have any exception specification. In your code you try to overload rand(), but the signature is the same as the one from <stdlib.h> except the exception specifier (which is not part of the function type, so cannot overload on it alone), hence you get a compile-time error (not a linker error, as you mentioned in the question).

If you wonder why the function rand() silently included is also visible in the global namespace (not visible only as std::rand as you may expect), that’s because often the C library functions are imported into the standard C++ header files via a direct

// <new_cpp_header>
#include <old_c_header.h> 

followed by

namespace std
{
    using old_function_from_old_c_header;
} 

so the function ends up in both global namespace as well as in namespace std;. This is not a very good practice IMO, but that’s how most compilers do it nowadays.

For example, the <cstdio> file has:

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

so both printf and std::printf are visible, even though you include only <cstdio> (and not <stdio.h>).

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement