LINUX.ORG.RU

[c] Почему к имени поля структуры добавляют сокращенное имя структуры?

 


0

1

Например,

struct stat {
               dev_t     st_dev;     /* ID of device containing file */
               ino_t     st_ino;     /* inode number */
               mode_t    st_mode;    /* protection */
               nlink_t   st_nlink;   /* number of hard links */
...
           };

или

struct sockaddr_in {
    short            sin_family;   // e.g. AF_INET, AF_INET6
    unsigned short   sin_port;     // e.g. htons(3490)
    struct in_addr   sin_addr;     // see struct in_addr, below
    char             sin_zero[8];  // zero this if you want to
};

Я понимаю, что это нужно для написания небольшого короткого имени переменной структуры

struct sockaddr_in a;

, и краткое непонятное имя переменной структуры компенсируется расширенным именем поля структуры с префиксом

a.sin_family = AF_INET4;

Или для это нужно для чего-то другого?

★★

в сях нет алиасов, в т.ч. для полей структур/объединений. для этого их кто-то однажды придумал делать дефайнами, поэтому и префиксы — чтобы иметь возможность в будущем изменить внутреннее представление структуры и сделать алиас старого имени поля на новое поле.

arsi ★★★★★
()
Ответ на: комментарий от arsi

например, man gethostbyname

struct hostent {
	char  *h_name;            /* official name of host */
	char **h_aliases;         /* alias list */
	int    h_addrtype;        /* host address type */
	int    h_length;          /* length of address */
	char **h_addr_list;       /* list of addresses */
}
#define h_addr h_addr_list[0] /* for backward compatibility */

h_addr — и есть такой алиас.

arsi ★★★★★
()
Ответ на: комментарий от arsi

можешь пример привести? А то непонятно :). Но С моей точки зрения то что ты говоришь всё равно ABI должно ломать т.к. меняются размеры структур(если только там какой-нить padding не сделали который потому уменьшают чтобы влезли новые поля). А раз так то смысла в этом нет.

true_admin ★★★★★
()
Ответ на: комментарий от arsi

Я верно понял - это если вдруг я захочу убрать sin_family и сделать, например, family вместо него, то надо сделать так:

#define sin_family family

struct a {
        int family;
};

main()
{
        struct a a1;
        a1.family = 1;
        a1.sin_family = 10;
}

?

Если так, то этот метод позволит только _переименовать_ поле структуры, не более?

bk_ ★★
() автор топика
Ответ на: комментарий от arsi

т.е. если бы там было просто addr, то таким алиасом они бы сломали все приложения, в которых присутствует переменная или функция с именем addr. а так сломают только те, где используется идентификатор h_addr :)

arsi ★★★★★
()
Ответ на: комментарий от bk_

> Если так, то этот метод позволит только _переименовать_ поле структуры, не более?

нет. в примере чуть выше — не просто переименование. ещё помню такое было где-то в signal.h, сейчас поищу…

arsi ★★★★★
()
Ответ на: комментарий от arsi

/usr/include/asm/signal.h:

struct sigaction {
        union {
          __sighandler_t _sa_handler;
          void (*_sa_sigaction)(int, struct siginfo *, void *);
        } _u;
        sigset_t sa_mask;
        unsigned long sa_flags;
        void (*sa_restorer)(void);
};

#define sa_handler      _u._sa_handler
#define sa_sigaction    _u._sa_sigaction
arsi ★★★★★
()
Ответ на: комментарий от arsi
struct sigvec
  {
    __sighandler_t sv_handler;  /* Signal handler.  */
    int sv_mask;                /* Mask of signals to be blocked.  */

    int sv_flags;               /* Flags (see below).  */
# define sv_onstack     sv_flags /* 4.2 BSD compatibility.  */
  };

Оно, например?

bk_ ★★
() автор топика

Это анахронизм - в древнейших компиляторах Си поля структур выносились в глобальное пространство имен.

tailgunner ★★★★★
()
Ответ на: комментарий от arsi

Понял.

То есть, такие префиксы разумно применять при условии потенциальных изменений структуры?

bk_ ★★
() автор топика
Ответ на: комментарий от bk_

Ведь в современном С-коде (e.g., git) такое не применяется?

bk_ ★★
() автор топика
Ответ на: комментарий от arsi

UPDATED

Такие префиксы имеет смысл применять при _необходимости бинарной совместимости_, т.е., сохранить padding.

bk_ ★★
() автор топика
Ответ на: комментарий от bk_

> То есть, такие префиксы разумно применять при условии потенциальных изменений структуры?

ох… имхо, такой подход лучше вообще не применять.

arsi ★★★★★
()
Ответ на: комментарий от arsi

Какое убожество. Это не решение проблемы, это возможное её усугубление в будущем.

Если мне взбредет в голову назвать поле в своей структуре h_addr, то при изменении api прийдется люто срать кирпичами от неожиданных проблем.

pathfinder ★★★★
()
Ответ на: комментарий от pathfinder

Именно поэтому теперь так не делают. Вопрос только почему так делали раньше разработчики, например, BSD-sockets?

bk_ ★★
() автор топика
Ответ на: UPDATED от bk_

для сохранения бинарной совместимости есть много подходов, и этот только один из них. имхо, самый взрывоопасный.

arsi ★★★★★
()
Ответ на: комментарий от bk_

ну… например, мелкософт-вей: вводить новые структуры с суффиксом Ех :) обычно они содержат не-Ех структуру и дополнительные поля. если структура имеет поле для флагов и там остались свободные биты, можно добавить в новой версии дополнительные поля в конец структуры и новый флаг, указывающий на наличие таких полей. если некоторое поле может принимать некорректное значение (что было ошибкой для старого апи), то это значение можно использовать для нового опять же как признак наличия дополнительных полей (например, если размер или позиция в файле раньше задавалась 32-битным полем, то в новой версии если размер равен -1 (или другому «магическому» числу), структура воспринималась как новая, с дополнительным 64-битовым полем). часто встречал структуры с полем, куда необходимо было записать размер этой структуры. это те, что вспомнил)

arsi ★★★★★
()

Потому что в до-K&R C имена полей структур были глобальными.

Yareg ★★★
()
Ответ на: комментарий от bk_

>Если так, то этот метод позволит только _переименовать_ поле структуры, не более?
там не только переименование. там тип поля поменялся. собственно, поэтому и переименовали.

xydo ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.