Ich habe ein *.cpp
Datei, die ich mit C ++ kompiliere (kein C-Compiler). Die enthaltende Funktion basiert auf einer Besetzung (siehe letzte Zeile), die in C definiert zu sein scheint (bitte korrigieren, wenn ich falsch liege!), Aber nicht in C ++ für diesen speziellen Typ.
[...] 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 [...]
Ist dieses Verhalten jetzt definiert oder undefiniert, da ich es in einer C ++ - Datei kompiliere? Oder müsste ich dies in eine *.c
Datei verschieben, um das Verhalten zu definieren?
c++
c
undefined-behavior
Daniel Stephens
quelle
quelle
.c
Erweiterung hat, wird der C-Compiler normalerweise automatisch aufgerufen.Antworten:
Dies ist sowohl in C ++ als auch in C definiert. Es verstößt nicht gegen strenge Aliasing-Bestimmungen, da der resultierende Zeiger nicht dereferenziert wird.
Hier ist das Zitat aus C ++ (dank @interjay und @VTT), das dies ermöglicht:
Hier ist das Zitat von C (danke @StoryTeller), das dies ermöglicht:
Diese geben an, dass ein Zeigertyp ohne Konsequenz in einen anderen Zeigertyp konvertiert (und dann optional zurückkonvertiert) werden kann.
Und hier ist das Zitat von POSIX , das diesen speziellen Fall zulässt:
Da diese Funktion (
bind
) Teil der C-Standardbibliothek ist, weist alles, was im Inneren vor sich geht (insbesondere das Dereferenzieren des typgesteuerten Zeigers), kein undefiniertes Verhalten auf.Um die allgemeinere Frage zu beantworten:
C und C ++ sind zwei verschiedene Sprachen. Wenn etwas in C definiert ist, aber nicht in C ++, ist es in C definiert, aber nicht in C ++. Keine implizite Kompatibilität zwischen den beiden Sprachen wird dies ändern. Wenn Sie Code verwenden möchten, der in C gut definiert, in C ++ jedoch nicht definiert ist, müssen Sie einen C-Compiler verwenden, um diesen Code zu kompilieren.
quelle
bind
sollte a seinconst void *
, geht jedochbind
der Existenz vonvoid
in der C-Sprache (und der Existenz von C ++ überhaupt) voraus. Sie haben es irgendwann aktualisiert, um den Basistyp hinzuzufügenconst
, aber nie behoben.Aufrufe zwischen C- und C ++ - Code rufen aus Sicht der jeweiligen Standards alle undefiniertes Verhalten auf, aber die meisten Plattformen spezifizieren solche Dinge.
In Situationen, in denen Teile des C- oder C ++ - Standards und die Dokumentation einer Implementierung zusammen eine Aktion definieren oder beschreiben, andere Teile sie jedoch als undefiniert charakterisieren, können Implementierungen Code auf eine Weise verarbeiten, die den Anforderungen ihrer Kunden am besten entspricht, oder - wenn dies der Fall ist Kundenbedürfnisse sind gleichgültig - egal welche Mode sie für richtig halten. Die Tatsache, dass der Standard solche Angelegenheiten als außerhalb ihrer Zuständigkeit liegend betrachtet, impliziert keine Beurteilung darüber, wann und / oder wie Implementierungen, die die Eignung für verschiedene Zwecke beanspruchen, sie sinnvoll verarbeiten sollten, aber einige Compiler-Betreuer unterschreiben einen Mythos, dass dies der Fall ist.
quelle