Mam *.cpp
plik, który kompiluję za pomocą C ++ (nie kompilatora w języku C). Funkcja zawierająca opiera się na rzutowaniu (patrz ostatni wiersz), który wydaje się być zdefiniowany w C (popraw, jeśli się mylę!), Ale nie w C ++ dla tego specjalnego typu.
[...] 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 [...]
Skoro kompiluję to w pliku C ++, czy jest to teraz zdefiniowane czy niezdefiniowane zachowanie? A może powinienem przenieść to do *.c
pliku, aby zdefiniować zachowanie?
c++
c
undefined-behavior
Daniel Stephens
źródło
źródło
.c
rozszerzenie, kompilator C jest wywoływany automatycznie.Odpowiedzi:
Jest to zdefiniowane zarówno w C ++, jak i C. Nie narusza to ścisłych przepisów dotyczących aliasingu, ponieważ nie wyklucza wynikowego wskaźnika.
Oto cytat z C ++ (dzięki @interjay i @VTT), który pozwala na to:
Oto cytat z C (dzięki @StoryTeller), który pozwala na to:
Określają one, że jeden typ wskaźnika można przekonwertować na inny typ wskaźnika (a następnie opcjonalnie przekonwertować z powrotem) bez konsekwencji.
Oto cytat z POSIX, który pozwala na ten konkretny przypadek:
Ponieważ ta funkcja (
bind
) jest częścią standardowej biblioteki C, cokolwiek dzieje się w środku (a konkretnie dereferencja wskaźnika rzutowanego na typ) nie ma niezdefiniowanego zachowania.Aby odpowiedzieć na bardziej ogólne pytanie:
C i C ++ to dwa różne języki. Jeśli coś jest zdefiniowane w C, ale nie w C ++, jest zdefiniowane w C, ale nie w C ++. Żadna domniemana zgodność między dwoma językami tego nie zmieni. Jeśli chcesz użyć kodu dobrze zdefiniowanego w C, ale niezdefiniowanego w C ++, będziesz musiał użyć kompilatora C do skompilowania tego kodu.
źródło
bind
powinien być aconst void *
, alebind
poprzedza istnienievoid
w języku C (i w ogóle C ++). W pewnym momencie zaktualizowali go, aby dodaćconst
, ale nigdy nie naprawili podstawowego typu.Wywołania między kodami C i C ++ wywołują Niezdefiniowane zachowanie z punktu widzenia odpowiednich standardów, ale większość platform określa takie rzeczy.
W sytuacjach, w których części standardu C lub C ++ oraz dokumentacja implementacji razem definiują lub opisują działanie, ale inne części określają je jako Niezdefiniowane, implementacje mogą przetwarzać kod w dowolny sposób, który najlepiej zaspokoi potrzeby klientów lub - jeśli są obojętni na potrzeby klientów - niezależnie od mody, którą uznają za stosowną. Fakt, że Standard traktuje takie kwestie jako będące poza ich jurysdykcją, nie implikuje żadnego osądu co do tego, kiedy i / lub w jaki sposób implementacje twierdzące, że są odpowiednie do różnych celów, powinny je w znaczący sposób przetwarzać, ale niektórzy opiekunowie kompilatorów zgadzają się z tym mitem.
źródło