Would does the following code crash during run-time when built with clang (but not gcc) unless I include a copy constructor for the TableTypeCarrier template class? If I include that copy constructor why do I experience the same run-time crash when built with gcc?
I have the following c++ classes defined:
class TableTypeCarrierBase {};
template<class T>
class TableTypeCarrier: public TableTypeCarrierBase {
public:
TableTypeCarrier(const T * const p) : m_p(p) {}
#ifdef __clang__
TableTypeCarrier(const TableTypeCarrier<T>& o) : m_p(o.m_p) {}
#endif
const T * Get() const
{
return m_p;
}
private:
const T * const m_p;
};
struct PsiTable {
PsiTable() : m_priv(NULL) { }
template<typename T> void Set(const TableTypeCarrier<T> inT)
{
m_priv = &inT;
}
template<typename T> const T * Get() const
{
return (!m_priv) ? NULL : ((TableTypeCarrier<T>*)m_priv)->Get();
}
private:
const TableTypeCarrierBase *m_priv;
};
You'll notice that the copy constructor of the TableTypeCarrier class template is conditionalized to only be built by clang and not gcc.
While writing this code originally (without the above conditionalized copy constructor), I was only using gcc to build and test it. When I tried to test it built with clang, the build would always succeed, but there would be a run-time crash while manipulating objects of these classes.
I spent months debugging this. I don't exactly recall the path that led me to try adding a copy constructor to the TableTypeCarrier template class, but indeed that solved the problem with my binaries built using clang. Unfortunately, simply having this copy constructor declared seemed to cause the same problem as originally described, but only when built using gcc.
Naturally, I added precompiler directives to conditionalize the copy constructor only if built using clang.
This fix worked for me, but I want to understand why.
If you need context to fully understand the problem, here is a link to the header that defines these classes within the full project at a point in history when this exact code was still present:
https://github.com/mkrufky/libdvbtee/blob/v0.4.0/libdvbtee/decode/table/table.h
I have since refactored the code and removed the TableTypeCarrierBase class and TableTypeCarrier template classes alltogether, as these were unnecessary proxies. Despite removing this code, I still want to understand why binaries built with clang vs binaries built with gcc behave differently when TableTypeCarrier has (or lacks) a copy constructor.
Why does a clang-built binary require this copy constructor? Why does a gcc-built binary crash if I include it?
-
Are you sure you hade no undefined behavior anywhere else in your code? I think that no one except you can say this, unless you provide an MCVEPetr– Petr2015年11月21日 17:43:39 +00:00Commented Nov 21, 2015 at 17:43
-
I'm not sure what else I can provide (apart from the github link) to make my example more complete :-/ Any other code that uses these classes would be too much to paste into this question post, in my opinion.mkrufky– mkrufky2015年11月21日 17:46:39 +00:00Commented Nov 21, 2015 at 17:46
-
3You should not just provide some additional code. You should make an MCVE, which means removing extra code unless you are absolutely sure nothing more can be removed.Petr– Petr2015年11月21日 17:49:44 +00:00Commented Nov 21, 2015 at 17:49
-
Thank you for the feedback. This will help me ask better questions in the future. However, somebody has already found a problem with the code that might lead to the answer to my question, so I'm hoping the question doesn't get closed.mkrufky– mkrufky2015年11月21日 18:04:54 +00:00Commented Nov 21, 2015 at 18:04
1 Answer 1
I see a problem here:
template<typename T> void Set(const TableTypeCarrier<T> inT)
{
m_priv = &inT;
}
You are passing the argument by value (and hence making a copy of it), but then you are taking the address of it and assigning it to a member variable. When the function ends, the object you took the address of disappears leaving a dangling pointer.
A compiler on a suitably high warning level should flag this.
7 Comments
Explore related questions
See similar questions with these tags.