C++成员函数内部PTHREAD_MUTEX_INITIALIZER无法编译

PTHREAD_MUTEX_INITIALIZER inside C++ member function cannot compile?

本文关键字:INITIALIZER 编译 MUTEX C++ 函数 内部 PTHREAD 成员      更新时间:2023-10-16
class A {
    public:
        A();
    private:
        pthread_mutex_t mu;
};
A::A()
{
    mu = PTHREAD_MUTEX_INITIALIZER;  //cannot compile
}

我不能在类成员函数中初始化pthread_mutex_t吗?

取而代之的是:

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

试试这个:

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

PTHREAD_MUTEX_INITIALIZER是一个宏,一个 C 结构初始值设定项,用于类似 {0,0,0,0,0{0}} 的东西,只能在定义时使用。

在这种情况下使用 pthread_mutex_init,因为常量用于编译时初始化。

即使我们将其更改为在构造函数中使用初始值设定项列表,它仍然失败:

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

我们可以通过查看预处理器的输出来了解它失败的原因,并且仅在少数上下文中用于初始化:

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

像 C++03 那样使用嵌套大括号进行初始化是不合法的,但更有趣的是,C++11 使这种语法和用法完全合法。

在您的原始代码中,我们可以看到更多内容:

A::A()
{
    const pthread_mutex_t test = PTHREAD_MUTEX_INITIALIZER; //  initialization - fine
    mu = test; // assignment - fine
    mu = PTHREAD_MUTEX_INITIALIZER;  // assignment - C++11 only
}
我喜欢

@askmish&@Diego的答案。我也喜欢@Flexo解释的内容。

但作为一个选项,如果您打算使用 PTHREAD_MUTEX_INITIALIZER 宏进行初始化,您可以做的是,在类定义中将互斥声明static如下所示:

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

然后,您可以在源文件中初始化此静态互斥锁,但在任何成员函数之外,如下所示:

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

您的选择:

  • 因此,要么保留宏并变为静态(如此处所示(。或
  • 您保持互斥锁的声明相同(非静态(,但在成员函数中使用 pthread_mutex_init() 函数(如其他人所指示的那样(。