Непредвиденная ошибка компиляции для определенного имени переменной sockaddr_in - PullRequest
0 голосов
/ 24 января 2019

Как часть функции, которая получает аргумент struct ifreq *ifr, если я объявляю struct sockaddr_in name;, программа компилируется, но если я назову переменную struct sockaddr_in ifr_addr;, произойдет сбой со следующей ошибкой:

code.c:244:24: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘.’ token
     struct sockaddr_in ifr_addr;
                        ^
code.c:244:24: error: expected expression before ‘.’ token
Makefile:2: recipe for target 'all' failed
make: *** [all] Error 1

Структура ifreq объявлена ​​как показано ниже.Я знаю, что структура имеет поле с тем же именем, что и проблемная переменная.Как это проблема в C?

       struct ifreq {
           char ifr_name[IFNAMSIZ]; /* Interface name */
           union {
               struct sockaddr ifr_addr;
               struct sockaddr ifr_dstaddr;
               struct sockaddr ifr_broadaddr;
               struct sockaddr ifr_netmask;
               struct sockaddr ifr_hwaddr;
               short           ifr_flags;
               int             ifr_ifindex;
               int             ifr_metric;
               int             ifr_mtu;
               struct ifmap    ifr_map;
               char            ifr_slave[IFNAMSIZ];
               char            ifr_newname[IFNAMSIZ];
               char           *ifr_data;
           };
       };

http://man7.org/linux/man-pages/man7/netdevice.7.html

1 Ответ

0 голосов
/ 24 января 2019

Когда вы получаете такую ​​ошибку, это почти всегда означает, что заголовок, в данном случае, вероятно, один из системных заголовков, определил макрос с тем же именем, которое вы выбрали для своей переменной, но с расширением, которое недопустимо в качестве идентификатора.

Вы не увидите проблемы, если заголовок определяет:

#define ifr_addr pwr_address

Вы видите проблему, если, как вы заметили в комментарии , расширение (в include/uapi/linux/if.h, около строки 258):

#define ifr_addr ifr_ifru.ifru_addr

Макрос предназначен для упрощения доступа к элементам объединения без необходимости каждый раз указывать имя члена объединения. В такие моменты вы задаетесь вопросом - стоило ли это того? (Я вижу это в кодовой базе, над которой я работаю ежедневно - много. Иногда трудно понять, к чему коду * обращаются.)

Хотя можно было бы использовать:

#undef ifr_addr

перед тем, как определить собственную переменную с таким именем, вы наступаете на тонкий лед. Лучше всего принять, что имя выгружено, и использовать что-то еще, хотя это и раздражает. Можно использовать ifr_srcaddr, чтобы сопоставить / контрастировать ifr_dstaddr.

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