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

Reply via email to