Указатель разыменования нарушает строгие правила сглаживания с использованием сокетов Беркли - PullRequest
11 голосов
/ 12 августа 2010

У меня есть код, который выглядит примерно так, где 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

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

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

Ответы [ 4 ]

5 голосов
/ 20 августа 2013

У меня была такая же проблема - похоже, ошибка в gcc.

Мне удалось обойти это с помощью

(*sin).sin_addr

вместо

sin->sin_addr
2 голосов
/ 12 августа 2010

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

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

с последующим использованием *act.

1 голос
/ 12 августа 2010

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

0 голосов
/ 12 августа 2010

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

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

...