I have something like this:
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
does not modify s
, and I would like to change the signature to
void some_func (const some_struct_t *s);
but the calls to pthreads
functions won't allow me to do that without warnings.
Is there any common idiom I could use to express that the some_struct_t
will be logically constant inside the function?
Any way to use some_func
from inside another function which has a const some_struct_t *s
without doing a cast?
some_func
modifies the mtx
member, so it cannot be const.
But you can make mtx
a pointer. You then still change the mutex, but that will no longer be covered by the 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);
}
Now some_func
no longer modifies s
, but initializing a some_struct
variable (and cleaning it up) has become a little bit more involved.
Expanding on koder's answer , you can have a redundant pointer inside some_struct_t
to the same mutex
, and use that instead of the address of the real 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);
}
Alternatively, you can trick the compiler by passing the pointer to the mutex
in another parameter, and hide that implementation detail to the programmer/user with a macro:
#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);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.