Разыменование указателя действительно нарушает строгие правила сглаживания с помощью сокетов Беркли

У меня есть код, который выглядит примерно так, где addr является sockaddr*:

struct sockaddr_in *sin = (struct sockaddr_in *) addr;
const char *IP=inet_ntoa(sin -> sin_addr);

Я полагаю, что это - очень типичный код для использования сокетов Беркли.

Однако, когда я компилирую это, я получаю соблюдающее предупреждение:
dereferencing pointer 'sin' does break strict anti-aliasing rules

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

Что надлежащий путь состоит в том, чтобы восстановить этот код, чтобы зафиксировать предупреждение и не просто заставить его замолчать?

11
задан GManNickG 12 August 2010 в 05:34
поделиться

3 ответа

Да, это известная проблема с gcc и сокетами. Проблема в основном в том, что способ разработки этого ip [46] несовместим с предположениями, которые, по мнению специалистов GCC, они могут сделать о наложении имен указателей.

Обычно я избегаю этого, сначала беря указатель на struct

struct in_addr* act = &(sin->sin_addr);

, а затем используя * act .

2
ответ дан 3 December 2019 в 11:20
поделиться

В зависимости от того, как вы использовали struct sockaddr , я думаю, что либо ваш код не работает, либо gcc. struct sockaddr и struct sockaddr_in имеют общий начальный элемент ( sa_family / sin_family ), поэтому он не нарушает правила псевдонима, если вы получили доступ только этот элемент через оба указателя; это разрешено C99. Более того, struct sockaddr не имеет других элементов, к которым вам разрешен доступ. Это в значительной степени непрозрачный тип для примитивного полиморфизма адресов сокетов. Если вы копались во внутренностях конкретной реализации в struct sockaddr или, что еще хуже, если вы объявили объект struct sockaddr , а не просто указатель или выполнили копирование между такими объектами, ваш код не работает. Если вы этого не сделали, и gcc выдает предупреждение о том, что вы нарушили правила псевдонима, то генерация предупреждения gcc не работает. Я, конечно, не удивлюсь, если это будет последнее.

1
ответ дан 3 December 2019 в 11:20
поделиться

Если ваш заголовочный файл и ваш компилятор являются частью одной и той же реализации C или C++, пожалуйтесь своему поставщику и попросите его поместить подходящую #pragma в его заголовочный файл, чтобы заставить замолчать его компилятор. Как реализатору, им разрешено играть в подобные игры, пока они предоставляют соответствующую реализацию.

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

-2
ответ дан 3 December 2019 в 11:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: