Что это значит в c ((TYPE) {}). Этот фрагмент взят из: __typeof__ (((TYPE) {}). MEMBER) - PullRequest
2 голосов
/ 09 ноября 2019
#define _IO_MEMBER_TYPE (type, member)       \
__typeof__ ( ((TYPE){}).MEMBER )

Я прочитал эту строку в заголовочном файле "libiop.h" в glibc, и я немного запутался в фигурных скобках {} после (TYPE). Если кто-нибудь может помочь мне понять это ( (TYPE){} )

Ответы [ 2 ]

2 голосов
/ 09 ноября 2019

Макрос обозначает тип определенного члена структуры. Комментарий пытается объяснить это:

/* Type of MEMBER in struct type TYPE.  */
#define _IO_MEMBER_TYPE(TYPE, MEMBER) __typeof__ (((TYPE){}).MEMBER)

Макрос используется только здесь:

/* Essentially ((TYPE *) THIS)->MEMBER, but avoiding the aliasing
   violation in case THIS has a different pointer type.  */
#define _IO_CAST_FIELD_ACCESS(THIS, TYPE, MEMBER) \
  (*(_IO_MEMBER_TYPE (TYPE, MEMBER) *)(((char *) (THIS)) \
  + offsetof(TYPE, MEMBER)))

Эта конструкция использует различные расширения GCC для реализации наследования классов в стиле C ++. Прямой способ написания этого больше не работает (или не вызывает предупреждения) с последними версиями GCC. (Код libio и C ++ ABI, который он реализует, относятся к GCC 2.95 в 90-х годах.)

Этот код довольно плохой, и вы действительно не должны использовать его в качестве модели для чего-либо.

2 голосов
/ 09 ноября 2019

Если кто-нибудь может помочь мне понять это ( (TYPE){} )

Это не стандартный C, но он почти имеет форму составного литерала C99 типа TYPE (заключенный в скобки), что соответствует очевидной цели. Это нестандартно, поскольку заключенная в скобки часть составного литерала должна принимать ту же форму, что и инициализатор для обозначенного типа, а C не допускает пустых инициализаторов. Это изменение будет полностью стандартным всякий раз, когда TYPE обозначает структуру, объединение или тип массива:

((TYPE){0})

__typeof__ также является нестандартным, но имеет форму идентификатора, зарезервированного для реализации. использовать, так что это, несомненно, расширение, специфичное для реализации, так как можно было бы предположить, что принятие пустого списка инициализатора также.

...