Kean Johnston wrote on 22/07/2005 00:41:06:
[...]
>
> I hope someone can help me. I am C++ impaired, and I am getting
> the following error when trying to bootstrap the current 4.0.2
> CVS. The error is coming from include/ext/bitmap_allocator.h
> line 111. The relevant code snippet is:
>
> class _Mutex {
> __gthread_mutex_t _M_mut;
>
> // Prevent Copying and assignment.
> _Mutex(_Mutex const&);
> _Mutex& operator=(_Mutex const&);
>
> public:
> _Mutex()
> {
> if (__threads_enabled)
> {
> #if !defined __GTHREAD_MUTEX_INIT
> _GTHREAD_MUTEX_INIT_FUNCTION(&_M_mut);
> #else
> __gthread_mutex_t __mtemp = __GTHREAD_MUTEX_INIT;
> _M_mut = __mtemp; <<<<<<<< THIS CAUSES THE ERROR
> #endif
> }
> }
>
> I get the following error message from the compiler:
> error: no match for 'operator=' in
> '((__gnu_cxx::_Mutex)this)->__gnu_cxx::_Mutex::_M_Mut = __mtemp'
>
> */gcc/include/sys/types.h:678: note: candidates are: __pthread_mutex&
> __pthread_mutex::operator=(const __pthread_mutex&)
>
> The contents of sys/types.h at that location are:
> typedef volatile struct __pthread_mutex {
> mutex_t __pt_mutex_mutex;
> pid_t __pt_mutex_pid;
> thread_t __pt_mutex_owner;
> int __pt_mutex_depth;
> pthread_mutexattr_t __pt_mutex_attr;
> } pthread_mutex_t;
>
> If I remove the 'volatile' keyword, then everything just works.
> So, do I adjust fixincludes to remove the 'volatile' keyword,
> or is this some weird side effect of the recent discussions on
> volatile (which I didn't read).
>
The error makes perfect sense. __pthread_mutex has only one
assignment operator for it (implicitly generated by the compiler):
__pthread_mutex & operator=(const __pthread_mutex&).
When you try to pass a volatile __pthread_mutex (named as
pthread_mutex_t), the compiler can't pass it to the assignment
operator - because then `volatile' would be stripped off the
reference.
I have created a small test case to demonstrate this:
typedef volatile struct A{} Av;
void foo()
{
Av x;
x = Av();
}
This test gives an error with any compiler I could tested it with:
gcc-2.96, gcc-3.2.1, gcc-4.0.0, xlC-6.0.0
> Any help / advice appreciated.
>
> Oh PS ... if I change that from a simple assignment to:
> __builtin_memcpy((void *)&_M_mut, (const void *)&__mtemp,
> sizeof(__gthread_mutex_t));
I don't think it is a good idea in general to cast `volatile' away
from _M_mut in that way. I am not sure, but that may trigger
undefined behavior (the object is volatile, but it is being modified
through a non-volatile pointer). And this concern comes out from
the long thread on volatile.
Another option would be to define __gthread_mutex_t in terms of
struct __pthread_mutex
rather than using the volatile typedef.
> Then it also just works. I could of course adjust the header file
> to do that for the platform.
>
Do you know why the type itself is defined as volatile, as opposed to
declaring only relevant variables as volatile? What system is it anyway?
Michael