Array mit variabler Länge (VLA) in C++-Compilern

Lesezeit: 4 Minuten

Benutzer-Avatar
BiagioF

Wie wir bereits wissen, VLA (standardisiert in C99) gehören nicht zum Standard in C++.

Der folgende Code ist also “illegal” in C++:

void foo(int n) {
  int vla[n];
  for (int i = 0; i < n; ++i) {
    vla[i] = i;
  }
}

Trotzdem ist der Compiler (g++ und klirren++) akzeptiert den Code als gültige Syntax und erzeugt nur a Warnung im Falle -pedantic Flag ist aktiviert.

ISO C++ verbietet Arrays mit variabler Länge „vla“ [-Wvla]

Meine Fragen sind:

  • Warum akzeptiert der Compiler diese Deklaration?
    Der Compiler kann ein Array in welcher Länge nicht einfach ablehnen [is-no-know-at-compile-time]?
    Gibt es eine Art Kompatibilitätssyntaxregel, die befolgt werden muss?

  • Was sagt die Norm dazu?
    Aus dem erzeugten Assemblercode sehe ich, dass der Compiler wie ein normales Array in den Stack in der Schleife schreibt, aber ich kann nichts über das Standardverhalten finden.

  • Sie haben zwei Fragen gestellt, nicht eine.

    – Leichtigkeitsrennen im Orbit

    5. September 2016 um 16:27 Uhr

  • Compiler-Erweiterungen sind genau das. Erweiterungen.

    – StoryTeller – Unslander Monica

    5. September 2016 um 16:30 Uhr


  • „Erzeugt nur eine Warnung für den Fall -pedantic Flag ist aktiviert.” – das ist alles -pedantic Versprechen. -pedantic-errors macht stattdessen diese Fehler.

    – Millenniumbug

    5. September 2016 um 16:41 Uhr


  • Bitte verwenden Sie den vollständigen Namen, nicht das Akronym. Es ist nützlicher für die ganze Community, nicht immer professionell

    – Jacek Cz

    5. September 2016 um 17:38 Uhr

  • @JacekCz Danke für den Vorschlag, ich habe ihn bearbeitet

    – BiagioF

    5. September 2016 um 18:05 Uhr

Warum akzeptiert der Compiler diese Deklaration?

Weil seine Autoren sich dafür entschieden haben.

Insbesondere GCC erlaubt standardmäßig eine Menge Nicht-Standard-Zeug, das historisch von alten C-Compilern akzeptiert wurde. Sie mögen “Kompatibilität” in diesem Sinne.

Was sagt die Norm dazu [it]?

Genau das, was die Warnung besagt, sagt sie darüber aus: ISO C++ verbietet Arrays mit variabler Länge.

C++ hat keine VLAs.

Wo Sie sehen, dass eine akzeptiert wird, handelt es sich um eine Compiler-Erweiterung. Um herauszufinden, wie dieser Compiler eine solche Erweiterung implementiert, müssten Sie die Autoren des Compilers fragen (oder gegebenenfalls seine Quelle untersuchen).

  • “Forbid” ist ein bisschen stark. Generell verbietet der Standard Erweiterungen nicht. Solange eine Implementierung richtig geformte Programme und Issues korrekt handhabt erforderlich Diagnose, es ist eine konforme Implementierung. Wenn die Implementierung auch reproduzierbares Verhalten für bestimmte schlecht geformte Programme bereitstellt, ist sie immer noch genauso konform; der Standard kümmert sich nicht um schlecht geformte Programme.

    – Rici

    5. September 2016 um 19:13 Uhr

  • @rici Sag das den GCC-Entwicklern! “Der Standard kümmert sich nicht um schlecht geformte Programme” Es tut! Es schreibt einfach nicht vor, dass sie bei der Übersetzung durchfallen. Dieses “Erweiterungen sind erlaubt” ergibt sich aus dieser Nachsicht.

    – Leichtigkeitsrennen im Orbit

    5. September 2016 um 19:14 Uhr


  • Inwiefern unterscheidet sich meine Aussage vom Verhalten von gcc? Ich denke, die Nachsicht ist völlig angemessen; es erlaubt Compilern, vorgeschlagene Ergänzungen zur Sprache zu implementieren und zu testen, was sowohl gcc- als auch clang-Entwickler tun. (Und wie drückt der Standard seine Besorgnis über schlecht gestaltete Programme aus? Es reicht aus, sie als schlecht gestaltet zu bezeichnen und ihr Verhalten ausdrücklich nicht zu definieren.)

    – Rici

    5. September 2016 um 19:38 Uhr

  • @rici: Die Warnmeldung lautet “ISO C++ verbietet Arrays variabler Länge”. Sie sagen “der Standard verbietet Erweiterungen nicht”. Ich kann nicht weiter darauf eingehen, wie sich die beiden Behauptungen unterscheiden, ohne mich mit dem grundlegenden Leseverständnis zu befassen, das Sie sicher nicht benötigen 🙂

    – Leichtigkeitsrennen im Orbit

    5. September 2016 um 19:39 Uhr

  • “Und wie drückt der Standard seine Besorgnis über schlecht gestaltete Programme aus? Es reicht aus, sie als schlecht gestaltet zu bezeichnen und ihr Verhalten ausdrücklich nicht zu definieren.” Ja, so drückt sie ihre Besorgnis aus. Wenn es ihm egal wäre, würde es sie nicht einmal erwähnen.

    – Leichtigkeitsrennen im Orbit

    5. September 2016 um 19:40 Uhr

Der Standard verlangt, dass ein konformer Compiler „eine Diagnose ausgeben“ muss, wenn er auf etwas Unzulässiges stößt. Danach steht es Ihnen frei, den Code mit einer implementierungsspezifischen Bedeutung weiter zu kompilieren. (Beachten Sie, dass “mit einer implementierungsspezifischen Bedeutung” eine höfliche Form von “mit undefiniertem Verhalten” ist).

  • Wahrscheinlich nicht gerade “undefiniertes Verhalten”: Undefiniertes, nicht spezifiziertes und implementierungsdefiniertes Verhalten

    – Brent Bradburn

    25. September 2019 um 15:46 Uhr

  • @nobar – der Standard sagt nicht, was der Code tut, und es ist nicht erforderlich, dass die Implementierung dokumentiert, was er tut. Das ist “undefiniertes Verhalten”. Exakt.

    – Peter Becker

    25. September 2019 um 18:36 Uhr

  • Wenn es UB gibt und der Compiler beschließt, genau zu dokumentieren, welchen Code er in diesem Fall ausgibt, wird es effektiv zu einem implementierungsdefinierten Verhalten auf dieser Plattform: Sie können es sicher auf dieser Plattform verwenden, aber der Code ist nicht auf andere Plattformen portierbar mehr. So wie Sie sich darauf verlassen hatten sizeof(int) == 4.

    – Cmaster – Wiedereinsetzung von Monica

    14. September 2020 um 13:29 Uhr

1015980cookie-checkArray mit variabler Länge (VLA) in C++-Compilern

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy