获取结构中 pthread_mutex 初始化的缺少大括号警告

Getting missing-braces warning for pthread_mutex initialization in struct

我有一个 struct fifo,其中包含类型 pthread_mutex_tpthread_cond_t。这些类型有什么特别之处,我不应该用 {0} 初始化它们吗?

#include <stdio.h>
#include <pthread.h>

struct fifo {
        pthread_mutex_t head_mutex;
        pthread_cond_t cond_add;
};
typedef struct fifo fifo;

fifo* fifo_construct(fifo* self)
{
        *self = (fifo){
            {0}, /* head_mutex */
            {0}, /* cond_add */
        };

        pthread_mutex_init(&self->head_mutex, NULL);
        pthread_cond_init(&self->cond_add, NULL);

        return self;
}

int main(int argc, char** argv)
{
        fifo f;
        fifo_construct(&f);

        pthread_mutex_t mut = {0}; // No complaint here!

        fprintf(stderr, "addr: %p, %p\n", &mut, &f.head_mutex);
}

使用 gcc -Wmissing-braces (10.2.0) 会产生以下警告:

fifo.c: In function ‘fifo_construct’:
fifo.c:12:10: warning: missing braces around initializer [-Wmissing-braces]
   12 |  *self = (fifo){
      |          ^
   13 |      {0}, /* head_mutex */
      |       {}
   14 |      {0}, /* cond_add */
      |       {}

但它并没有抱怨 main 中的初始化。我是不是遗漏了什么,还是编译器太挑剔了?

I have a struct fifo that contains types pthread_mutex_t and pthread_cond_t. Is there something special about these types that I shouldn't initialize them with {0}?

就C语言而言不是。 {0} 是任何类型对象的有效初始值设定项。然而,这并不意味着所得到的互斥量或 CV 值在 pthreads 级别是有效的。

Using gcc -Wmissing-braces (10.2.0) produces the following warning: [...]

这是一个样式警告,您可以从任何数量的相似结构类型的相似初始值设定项中获得它。这并不一定意味着您的代码有任何问题。 GCC 只是认为这是一种冒险的方法,尽管 {0} 初始化形式的特殊情况完全是惯用的。

其他选项包括

  • 使用 pthreads 为这些类型提供的初始化宏*:

    *self = (fifo) { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER };
    

    在这种情况下,您不需要同时调用初始化函数,除非您需要非默认属性。

  • 省略这些成员的任何显式初始值设定项。

  • 如果在示例代码中,mutex 和 CV 是唯一的成员,或者如果您不关心初始化任何其他成员,则删除整个赋值语句及其复合文字。当您无论如何要在使用它们之前通过它们的初始化函数初始化它们时,您不需要预先初始化互斥锁和 CV。

  • -Wno-missing-braces

    关闭警告

*POSIX 规范的旧版本仅承诺这些可用于具有静态存储持续时间的对象,但该警告已从最新版本中删除。