716 Stimmen

Kann Code, der sowohl in C als auch in C++ gültig ist, ein unterschiedliches Verhalten zeigen, wenn er in jeder Sprache kompiliert wird?

C und C++ haben viele Unterschiede, und nicht jeder gültige C-Code ist auch ein gültiger C++-Code.
(Mit "gültig" meine ich Standardcode mit definiertem Verhalten, d. h. nicht implementierungsspezifisch/undefiniert/etc.)

Gibt es ein Szenario, in dem ein Stück Code, das sowohl in C als auch in C++ gültig ist, zu verschiedene Verhalten bei der Kompilierung mit einem Standardcompiler in jeder Sprache?

Um einen vernünftigen/brauchbaren Vergleich zu machen (ich versuche, etwas praktisch Nützliches zu lernen, und nicht, offensichtliche Schlupflöcher in der Frage zu finden), nehmen wir an:

  • Nichts, was mit dem Präprozessor zusammenhängt (d.h. keine Hacks mit #ifdef __cplusplus pragmas, etc.)
  • Alles, was die Implementierung betrifft, ist in beiden Sprachen gleich (z. B. numerische Grenzwerte usw.)
  • Wir vergleichen relativ neue Versionen der einzelnen Standards (z. B. C++98 und C90 oder später).
    Wenn die Versionen eine Rolle spielen, dann geben Sie bitte an, welche Versionen der einzelnen Programme ein unterschiedliches Verhalten zeigen.

490voto

Seth Carnegie Punkte 72029

Hier ein Beispiel, das den Unterschied zwischen Funktionsaufrufen und Objektdeklarationen in C und C++ ausnutzt, sowie die Tatsache, dass C90 den Aufruf nicht deklarierter Funktionen erlaubt:

#include <stdio.h>

struct f { int x; };

int main() {
    f();
}

int f() {
    return printf("hello");
}

In C++ wird dies nichts ausgeben, da eine temporäre f erstellt und zerstört wird, aber in C90 wird es gedruckt hello weil Funktionen aufgerufen werden können, ohne deklariert worden zu sein.

Falls Sie sich über den Namen gewundert haben f zweimal verwendet wird, erlauben die C- und C++-Standards dies ausdrücklich, und um ein Objekt zu erzeugen, muss man sagen struct f zu disambiguieren, wenn Sie die Struktur wollen, oder lassen Sie struct wenn Sie die Funktion wünschen.

469voto

Jerry Coffin Punkte 452852

Für C++ im Vergleich zu C90 gibt es mindestens eine Möglichkeit, ein anderes Verhalten zu erreichen, das nicht durch die Implementierung definiert ist. In C90 gibt es keine einzeiligen Kommentare. Mit ein wenig Sorgfalt können wir dies nutzen, um einen Ausdruck mit völlig unterschiedlichen Ergebnissen in C90 und in C++ zu erstellen.

int a = 10 //* comment */ 2 
        + 3;

In C++ wird alles von der // bis zum Ende der Zeile ist ein Kommentar, so dass sich dies wie folgt auswirkt:

int a = 10 + 3;

Da C90 keine einzeiligen Kommentare kennt, wird nur die /* comment */ ist ein Kommentar. Die erste / und die 2 sind beide Teile der Initialisierung, so dass sich folgendes ergibt:

int a = 10 / 2 + 3;

So ergibt ein korrekter C++-Compiler 13, ein streng korrekter C90-Compiler jedoch 8. Natürlich habe ich hier nur willkürliche Zahlen gewählt - Sie können andere Zahlen verwenden, wie Sie es für richtig halten.

419voto

Alexey Frunze Punkte 59460

Das Folgende, gültig in C und C++, wird (höchstwahrscheinlich) zu unterschiedlichen Werten in i in C und C++:

int i = sizeof('a');

Véase Größe des Zeichens ('a') in C/C++ um den Unterschied zu erläutern.

Eine weitere von dieser Artikel :

#include <stdio.h>

int  sz = 80;

int main(void)
{
    struct sz { char c; };

    int val = sizeof(sz);      // sizeof(int) in C,
                               // sizeof(struct sz) in C++
    printf("%d\n", val);
    return 0;
}

196voto

detunized Punkte 14779

C90 vs. C++11 ( int vs. double ):

#include <stdio.h>

int main()
{
  auto j = 1.5;
  printf("%d", (int)sizeof(j));
  return 0;
}

In C auto bedeutet lokale Variable. In C90 ist es in Ordnung, den Variablen- oder Funktionstyp wegzulassen. Es wird standardmäßig auf int . In C++11 auto bedeutet etwas ganz anderes: Es weist den Compiler an, den Typ der Variablen aus dem Wert abzuleiten, mit dem sie initialisiert wurde.

132voto

godlygeek Punkte 1440

Ein weiteres Beispiel, das ich noch nicht gesehen habe und das einen Unterschied im Präprozessor hervorhebt:

#include <stdio.h>
int main()
{
#if true
    printf("true!\n");
#else
    printf("false!\n");
#endif
    return 0;
}

Dies gibt "false" in C und "true" in C++ aus - In C wird jedes undefinierte Makro als 0 ausgewertet. In C++ gibt es eine Ausnahme: "true" wird zu 1 ausgewertet.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X