class A {
public:
A();
private:
pthread_mutex_t mu;
};
A::A()
{
mu = PTHREAD_MUTEX_INITIALIZER; //cannot compile
}
Ca
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.
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
}
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:
pthread_mutex_init()
function (as others have indicated) inside your member-function.Use pthread_mutex_init in this case, as the constant is for compile-time initialization.