Reputation: 523
Could someone explain the behind the scene causes of inconsistent crashes for this user error.
Here is the main function
#include "foo.h"
inline int Bar(const int &a)
{
...
}
...
int b=Bar(a);
In "foo.C" there is also a copy of the function
inline int Bar(const int &a)
Here is the problem. I do not own foo.h nor foo.C, and there is no declaration of Bar(int) in foo.h.
Everything compiles and works fine with older version of foo.h and foo.C
After my co-worker updated some other functions in his foo.C, the code still compiles fine but it started to crashes on execution.
Debugging through ddd showed that when my main function calls for Bar(),it is actually calling the Bar() inside foo.C instead of my own defined Bar().
Of cause the fix was to static my own function or change the name of my own Bar() function.
I know writing code like this disorganized and is prone to error like this. Could someone explain to me why would the code crashes inconsistently?
Thank you all
Regards
Upvotes: 3
Views: 960
Reputation: 72449
inline functions still have external linkage. That is, they are emitted by the compiler into the corresponding object files and when the linker links the application it considers all functions having the same signature (including their name and enclosing namespace) to be the same. Since the function is defined inline
it chooses one of the definitions at random and drops the other, without an error. (This is a violation of the one definition rule, which causes undefined behavior according to the standard.)
To prevent this problem use anonymous namespace, like this:
namespace {
inline int Bar(const int &a)
{
...
}
}
In your case doing so in either foo.C or main will do the trick. Equivalently you could add static
:
static int Bar() {}
If you were writing in C.
Using an anonymous namespace or the static
keyword makes the function local to the translation unit, so the linker doesn't see it as an external symbol. This way you can have arbitrary amount of functions having the same signature in different translation units.
Upvotes: 2
Reputation: 4148
I think you're using the foo defined Bar function because it is #included via foo.h before you defined your own Bar function.
I am surprised your compiler is not warning you about the duplicate definition (illegal), but if you had defined your Bar function before #include "foo.h" an error should have been thrown.
This URL says the redefinition of an inline is illegal unless the inline is the same:
C static inline function redefinition rules
My compiler is throwing an error on this. The best way to avoid is to use a separate namespace or a macro guard..
Upvotes: 0