Почему <signal.h> препятствует использованию "si_" в качестве префикса для имени некоторых переменных? - PullRequest
0 голосов
/ 07 ноября 2018

Я отлаживал странную ошибку компиляции, которую я получал внутри своего кода, и я обнаружил, что не могу использовать префикс si_ для некоторых имен переменных (любого типа), если включен <signal.h>.

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

#include <signal.h>

int main(void)
{
    int si_value = 0;

    return 0;
}

Если я пытаюсь скомпилировать это с помощью компилятора GNU C gcc, я получаю следующую ошибку:

> gcc example.c
In file included from /usr/include/signal.h:57:0,
                 from example.c:2:
example.c: In function ‘main’:
example.c:6:9: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘.’ token
     int si_value = 0;
         ^
example.c:6:9: error: expected expression before ‘.’ token

Тем не менее, если я использую другое имя, например si_value2, ошибка не отображается. Для справки я использую GCC v7.3.0 на Ubuntu Mate 18.04.1 LTS. Такая же проблема наблюдается с g++.

Полагаю, такое поведение связано с определением макроса внутри заголовка <signal.h>, но после краткого изучения я не смог найти ничего действительно связанного.

Я, честно говоря, могу это исправить, просто используя другое имя. Однако меня беспокоит: как я мог бы элегантно избежать такого рода проблем в будущем?


Обновление: As @ F.X. предложил, используя gcc -E example.c показывает, что имя переменной раскрыто (следовательно, ошибка):

...
    int 
# 6 "example.c" 3 4
       _sifields._rt.si_sigval 
# 6 "example.c"
                = 0;
...

Ответы [ 2 ]

0 голосов
/ 07 ноября 2018

<signal.h> на самом деле не мешает использовать si_ в качестве префикса для ваших переменных.Однако спецификация POSIX гласит, что этот префикс зарезервирован, чтобы позволить заголовку и функциям библиотеки, которые он объявляет, использовать эти имена, не беспокоясь о том, что они будут конфликтовать с вашими собственными переменными.

Так что здесь происходит то, что si_value определено некоторым образом в заголовочном файле, возможно, как макрос или typedef, и ваша попытка использовать то же имя конфликтует с этим.Если бы вы использовали si_vy1ghad563nvy43wd, это, вероятно, сработало бы, но теоретически заголовок мог бы использовать это имя (думая, что это вряд ли будет конфликтовать с чем-либо, что бы использовал программист).

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

0 голосов
/ 07 ноября 2018

как я мог бы элегантно избежать подобных проблем в будущем?

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

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