Problem compiling libstdc++ is current 4.0.2 cvs (volatile strikes again)

Michael Veksler VEKSLER@il.ibm.com
Mon Jul 25 04:15:00 GMT 2005





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



More information about the Gcc mailing list