Путаница в определении pthread_attr_t - PullRequest
1 голос
/ 14 апреля 2019

Когда я нажимаю перейти к определению в коде VS, это приводит меня к:
/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h
и определение:

union pthread_attr_t
{
  char __size[__SIZEOF_PTHREAD_ATTR_T];
  long int __align;
};
#ifndef __have_pthread_attr_t
typedef union pthread_attr_t pthread_attr_t;
# define __have_pthread_attr_t 1
#endif

Что этоопределение союза?char массив или long целое число?Как его можно использовать для хранения атрибутов pthread?Абсолютно бессмыслица.


Затем я ищу pthread_attr_t в реализации glibc-master и нахожу 3 наиболее связанных случая: glibc-master/sysdeps/htl/bits/pthreadtypes.h:

#include <bits/types/struct___pthread_attr.h>
typedef struct __pthread_attr pthread_attr_t;

glibc-master/sysdeps/htl/bits/types/struct___pthread_attr.h:

Очевидно, этот должен быть правильным:

struct __pthread_attr
{
  struct sched_param __schedparam;
  void *__stackaddr;
  size_t __stacksize;
  size_t __guardsize;
  enum __pthread_detachstate __detachstate;
  enum __pthread_inheritsched __inheritsched;
  enum __pthread_contentionscope __contentionscope;
  int __schedpolicy;
};

glibc-master/sysdeps/nptl/bits/pthreadtypes.h:

union pthread_attr_t
{
  char __size[__SIZEOF_PTHREAD_ATTR_T];
  long int __align;
};
#ifndef __have_pthread_attr_t
typedef union pthread_attr_t pthread_attr_t;
# define __have_pthread_attr_t 1
#endif

Может кто-нибудь сказать мне, что здесь происходит?Понятия не имею об этом union определении. массив char или long целое число?Как его можно использовать для хранения атрибутов pthread?

Забыл сказать, я отлаживаю в CLion и вижу, что это структура union pthread_attr_t.

1 Ответ

2 голосов
/ 14 апреля 2019

Я думаю, что идея состоит в том, чтобы выставить эти типы как достаточно выровненные непрозрачные буферы достаточного размера. ( Более современный способ сделать это - использовать _Alignas вместо union:

struct {
  _Alignas(long int)
  char __size[__SIZEOF_PTHREAD_ATTR_T];
};

) Это позволяет объявлять эти типы в стеке (auto длительность хранения) или статически (static / extern) для удовлетворения API POSIX, но без раскрытия макета.

Технически, такой трюк - неопределенное поведение (нарушает строгий псевдоним), но при отдельной компиляции компиляторы не должны быть в состоянии испортить его.

Нет необходимости делать что-либо из этого, если есть достаточное согласие, что члены типа pthread_attr_t, если таковые имеются, не должны быть доступны напрямую, но я предполагаю, что glibc пытается сделать не одобряет такой доступ еще сильнее, чтобы не получать жалоб на семантические «поломки» в частных API, которые пользователи не должны использовать в первую очередь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...