0

我有这样的事情:

typedef struct
{
    pthread_mutex_t mtx;
    /* Other stuff */
} some_struct_t;

void some_func (some_struct_t *s)
{
    pthread_mutex_lock (&s->mtx);
    /* Some stuff */
    pthread_mutex_unlock (&s->mtx);
}

some_func不修改s,我想将签名更改为

void some_func (const some_struct_t *s);

但是对pthreads函数的调用不允许我在没有警告的情况下这样做。

有什么常见的习语可以用来表示函数内部的逻辑上将some_struct_t是不变的吗?

有什么方法可以some_func从另一个没有进行强制转换的函数内部使用const some_struct_t *s

4

2 回答 2

1

some_func修改mtx成员,所以它不能是 const。

但是你可以做mtx一个指针。然后您仍然更改互斥锁,但这将不再被 const 覆盖。

typedef struct
{
    pthread_mutex_t *mtx;
    /* Other stuff */
} some_struct_t;

void some_func(const some_struct_t *s)
{
    pthread_mutex_lock(s->mtx);
    /* Some stuff */
    pthread_mutex_unlock(s->mtx);
}

int main()
{
    pthread_mutex_t mtx = MUTEX_INITIALIZER;
    some_struct s = {
        .mtx = &mtx;
    };
    some_func(&s);
}

现在some_func不再修改s,但初始化some_struct变量(并清理它)变得更加复杂。

于 2020-12-29T16:07:16.487 回答
0

扩展koder 的答案some_struct_t,您可以在内部有一个冗余指针mutex,并使用它而不是真实的地址mutex

typedef struct
{
    pthread_mutex_t pmtx;
    pthread_mutex_t *mtx;
    /* Other stuff */
} some_struct_t;

void some_func (const some_struct_t *s)
{
    pthread_mutex_lock (s->mtx);
    /* Some stuff */
    pthread_mutex_unlock (s->mtx);
}

int main ()
{
    some_struct_t  s;

    pthread_mutex_init (&s.pmtx, NULL);
    s.mtx = &s.pmtx;
    some_func (&s);
    pthread_mutex_destroy (&s.pmtx);
}

或者,您可以通过将指针传递给mutex另一个参数来欺骗编译器,并使用宏将该实现细节隐藏给程序员/用户:

#define some_func(a)      some_func_hidden (a, &(a)->mtx)

typedef struct
{
    pthread_mutex_t mtx;
    /* Other stuff */
} some_struct_t;

void some_func_hidden (const some_struct_t *s, pthread_mutex_t *mtx)
{
    pthread_mutex_lock (mtx);
    /* Some stuff */
    pthread_mutex_unlock (mtx);
}

int main ()
{
    some_struct_t  s;

    pthread_mutex_init (&s.mtx, NULL);
    some_func (&s);
    pthread_mutex_destroy (&s.mtx);
}
于 2020-12-29T20:21:51.010 回答