PTHREAD_MUTEX_INITIALIZER inside C++ member function cannot compile?

前端 未结 4 1817
遇见更好的自我
遇见更好的自我 2020-12-17 02:00
class A {
    public:
        A();
    private:
        pthread_mutex_t mu;
};

A::A()
{
    mu = PTHREAD_MUTEX_INITIALIZER;  //cannot compile
}

Ca

相关标签:
4条回答
  • 2020-12-17 02:01

    Instead of this:

    A::A()
    {
        mu = PTHREAD_MUTEX_INITIALIZER;  //cannot compile
    }
    

    Try this:

    A::A()
    {
    pthread_mutex_init( &(mu), NULL);
    }
    

    The PTHREAD_MUTEX_INITIALIZER is a macro,a C struct initializer for something like {0,0,0,0,0{0}} and can only be used at the point of definition.

    0 讨论(0)
  • 2020-12-17 02:05

    Even if we change this to use an initializer list in the constructor it still fails:

    #include <pthread.h>
    
    struct foo {
      pthread_mutex_t test;
      foo() : test(PTHREAD_MUTEX_INITIALIZER) {}
    };
    
    int main() {
      foo f;
    }
    

    We can see why it fails and an only be used for initialisation in a few contexts by looking at the output from the pre-processsor:

    struct foo {
      pthread_mutex_t test;
      foo() : test({ { 0, 0, 0, 0, 0, { 0 } } }) {}
    };
    

    It's not legal to use nested braces for initialisation like that in C++03, but what's more interesting perhaps is that C++11 makes this syntax and usage perfectly legal.

    In your original code we can see a few more things:

    A::A()
    {
        const pthread_mutex_t test = PTHREAD_MUTEX_INITIALIZER; //  initialization - fine
        mu = test; // assignment - fine
        mu = PTHREAD_MUTEX_INITIALIZER;  // assignment - C++11 only
    }
    
    0 讨论(0)
  • 2020-12-17 02:10

    I like the answers from @askmish & @Diego. I like also what @Flexo explained.

    But just as an option, if you are intent on initializing with the PTHREAD_MUTEX_INITIALIZER macro, what you can do is, make the mutex declaration inside the class definition static like this:

    class A {
        public:
            A();
        private:
            static pthread_mutex_t mu;
    };
    

    And then you can initialize this static mutex in your source file BUT outside any member function, like this:

    class A {
        public:
            A();
        private:
            static pthread_mutex_t mu;
    };
    
    pthread_mutex_t A::mu = PTHREAD_MUTEX_INITIALIZER;
    
    A::A()
    {
    }
    

    Your options:

    • So either you keep the macro and go static (as shown here). OR,
    • you keep the declaration of the mutex the same (non-static) but use the pthread_mutex_init() function (as others have indicated) inside your member-function.
    0 讨论(0)
  • 2020-12-17 02:16

    Use pthread_mutex_init in this case, as the constant is for compile-time initialization.

    0 讨论(0)
提交回复
热议问题