I have been running into CodeGuard problems using boost 1.29.0 with
BorlandC++Builder 6Pro update 2 and CodeGuard. The test project is a
console app, multi-threading but no vcl (don't know if the VCL enabled
affects it or not).
The code is
#include
int main(int argc, char* argv[])
{
boost::mutex m;
return 0;
}
I get a resource type mismatch on exit which is down to the mutes. I have
linked directly with the source and found where the problem lies. It could
be down to 2 places:
a) boost allocates the mutex (mutex.cpp line 39) using the nowthrow operator
new
m_mutex = reinterpret_cast(new(std::nothrow) CRITICAL_SECTION);
and then deletes it using the standard delete (mutex.cpp line 48)
delete reinterpret_cast(m_mutex);
This causes slight problems as codeguard treats allocations from new and
malloc differently to check you free the memory correctly. nothrow new uses
malloc, so a standard delete is the incorrect way to free the mutex here
from CodeGuards point of view. I have changed the delete to
operator delete (reinterpret_cast(m_mutex),
std::nothrow);
which calls the nothrow version of delete. Unfortunately, the next part of
the problem:
b) For some reason, the mutex is using the roguewave stl new.h which
defines the nothrow operators as such
(oldstl\new.h line 143)
inline void * _RTLENTRY operator new (size_t size, const std::nothrow_t &nt)
{
size = size ? size : 1;
return malloc(size);
}
(oldstl\new.h line 152)
inline void _RTLENTRY operator delete (void *v, const std::nothrow_t &nt)
{
::operator delete (v); // The standard operator doesn't throw any
exceptions
}
Here, there is a conflict in the allocation and deallocation. changing line
154 to
free(v);
along with the change to mutex to use the nothrow version of delete fixes it
so codeguard can be used.
Looking in the stlport new, it forces us to use RogueWave's new because of
these lines in stlport\new line 49
# if !defined (_STLP_NO_NEW_NEW_HEADER)
# include _STLP_NATIVE_CPP_RUNTIME_HEADER(new)
# else
# include
# endif
which makes it include roguewaves version of new. So C++Builder 6 is still
reliant on roguewave stl even when set to use STLPort.
Possible solutions are
a) Make boost::thread use nothrow version of delete but this requires a fix
in the borland/rogue wave header for the delete to make it use free. or
b) mutex could use malloc and free directly for borland.
Which would people prefer or can anyone think of another solution?
Cheers
Russell