Reputation: 21510
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()
?
Upvotes: 0
Views: 166
Reputation: 56557
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>
).
Upvotes: 3