У меня есть *.cpp
файл, который я компилирую с C ++ (не компилятор C). Содержащая функция опирается на приведение (см. Последнюю строку), которое, кажется, определено в C (пожалуйста, исправьте, если я ошибаюсь!), Но не в C ++ для этого специального типа.
[...] C++ code [...]
struct sockaddr_in sa = {0};
int sockfd = ...;
sa.sin_family = AF_INET;
sa.sin_port = htons(port);
bind(sockfd, (struct sockaddr *)&sa, sizeof sa);
[...] C++ code [...]
Поскольку я компилирую это в файл C ++, это теперь определенное или неопределенное поведение? Или мне нужно переместить это в *.c
файл, чтобы определить поведение?
c++
c
undefined-behavior
Дэниел Стивенс
источник
источник
.c
расширение, компилятор C вызывается автоматически.Ответы:
Это определено как в C ++, так и в C. Это не нарушает строгих правил псевдонимов, поскольку не разыменовывает результирующий указатель.
Вот цитата из C ++ (благодаря @interjay и @VTT), которая позволяет это:
Вот цитата из C (спасибо @StoryTeller), которая позволяет это:
Они указывают, что один тип указателя может быть преобразован в другой тип указателя (и затем необязательно преобразован обратно) без последствий.
А вот цитата из POSIX, которая позволяет этот конкретный случай:
Так как эта функция (
bind
) является частью стандартной библиотеки C, все, что происходит внутри (в частности, разыменование приведенного к типу указателя), не имеет неопределенного поведения.Чтобы ответить на более общий вопрос:
C и C ++ - два разных языка. Если что-то определено в C, но не в C ++, это определяется в C, но не в C ++. Никакая подразумеваемая совместимость между этими двумя языками не изменит это. Если вы хотите использовать код, который четко определен в C, но не определен в C ++, вам придется использовать компилятор C для компиляции этого кода.
источник
bind
должно быть aconst void *
, но оноbind
предшествует существованию языкаvoid
C (и вообще C ++). Они обновили его в какой-то момент, чтобы добавитьconst
, но не исправили базовый тип.Все вызовы между кодом C и C ++ вызывают неопределенное поведение с точки зрения соответствующих стандартов, но большинство платформ определяют такие вещи.
В ситуациях, когда части стандарта C или C ++ и документация реализации вместе определяют или описывают действие, но другие части характеризуют его как неопределенный, реализации разрешается обрабатывать код любым способом, который лучше всего отвечает потребностям их клиентов или - если они безразличны к потребностям клиентов - независимо от того, что они считают подходящим. Тот факт, что Стандарт рассматривает такие вопросы как находящиеся вне их юрисдикции, не подразумевает какого-либо суждения относительно того, когда и / или как реализации, требующие пригодности для различных целей, должны обрабатывать их осмысленно, но некоторые сопровождающие компилятора подписываются на миф о том, что он делает.
источник