Der folgende Code wird unter gcc 4.8 und Clang 3.2 kompiliert:
int main()
{
int size = 10;
int arr[size];
}
8.3.4/1 des C++-Standards besagt, dass die Größe eines Arrays ein ganzzahliger konstanter Ausdruck sein muss, was size
scheint nicht zu sein. Ist das ein Fehler in beiden Compilern oder übersehe ich etwas?
Das neueste VC++ CTP lehnt den Code mit dieser interessanten Meldung ab:
error C2466: cannot allocate an array of constant size 0
Der interessante Teil ist, wie es scheint, das zu denken size
ist Null. Aber zumindest lehnt es den Code ab. Sollten gcc und Clang nicht dasselbe tun?
Das ist Arrays mit variabler Länge oder VLA die ein C99 Funktion aber gcc und klirren unterstützt es als Erweiterung in C++ während Visual Studio nicht. Damit Visual Studio
in diesem Fall dem Standard entspricht und fachlich korrekt ist. Um nicht zu sagen, dass Erweiterungen schlecht sind, die Der Linux-Kernel hängt von vielen gcc-Erweiterungen absodass sie in bestimmten Kontexten nützlich sein können.
Wenn Sie die hinzufügen -pedantic
beide markieren gcc
und clang
wird Sie z. B. davor warnen gcc
sagt (live sehen):
warning: ISO C++ forbids variable length array 'arr' [-Wvla]
int arr[size];
^
Verwendung der -pedantic-errors
Flag wird dies zu einem Fehler machen. Weitere Informationen zu Erweiterungen finden Sie in diesen Dokumenten Von GCC unterstützte Sprachstandards und clangs Abschnitt zur Sprachkompatibilität.
Aktualisieren
Die Entwurf des C++-Standards deckt ab, was a ist integraler konstanter Ausdruck im Abschnitt 5.19
Konstante Ausdrücke Absatz 3 und sagt:
Ein ganzzahliger konstanter Ausdruck ist ein Ausdruck vom ganzzahligen oder unbegrenzten Aufzählungstyp, der implizit in einen Prvalue konvertiert wird, wobei der konvertierte Ausdruck ein konstanter Kernausdruck ist. […]
Aus der Lektüre dieses Artikels ist nicht intuitiv ersichtlich, welche Möglichkeiten es gibt Boosts Codierungsrichtlinien für ganzzahlige konstante Ausdrücke macht das super.
In diesem Fall, da Sie initialisieren size
mit einer wörtlich verwenden konst würde ausreichen, um es zu machen integraler konstanter Ausdruck (sehen [expr.const]p2.9.1) und bringen Sie den Code auch wieder auf den Standard C++:
const int size = 10;
verwenden constexpr würde auch funktionieren:
constexpr int size = 10;
Es würde wahrscheinlich helfen, den Unterschied zwischen zu lesen constexpr
und const
.
Als Referenz den entsprechenden Abschnitt zu 8.3.4
Absatz 1 in dem C99-Standardentwurf Abschnitt wäre 6.7.5.2
Array-Deklaratoren Absatz 4 was sagt (Betonung von mir):
Wenn die Größe nicht vorhanden ist, ist der Arraytyp ein unvollständiger Typ. Wenn die Größe * anstelle eines Ausdrucks ist, ist der Array-Typ ein Array-Typ mit variabler Länge und unspezifizierter Größe, der nur in Deklarationen mit Funktionsprototypbereich verwendet werden kann;124) solche Arrays sind dennoch vollständige Typen. Wenn die Größe ein ganzzahliger konstanter Ausdruck ist und der Elementtyp eine bekannte konstante Größe hat, ist der Array-Typ kein Array-Typ mit variabler Länge; andernfalls ist der Array-Typ ein Array-Typ mit variabler Länge.
Array mit variabler Länge ist nur C, nicht C++. gcc und clang unterstützen es jedoch als Erweiterung.
– Bryan Chen
22. Januar 2014 um 3:54 Uhr
Könnte eine Erweiterung für Arrays mit variabler Länge in C++1y und/oder C99 vorgeschlagen werden?
– Yakk – Adam Nevraumont
22. Januar 2014 um 3:55 Uhr
std::valarray
wird in C++1y vorgeschlagen– Bryan Chen
22. Januar 2014 um 3:56 Uhr
@BryanChen, du denkst wahrscheinlich an
std::dynarray
aber sowohl das als auch VLAs sind in einem TS AFAIK.– Chris
22. Januar 2014 um 3:57 Uhr
Dies war eine der fruchtbareren Fragen, die ich seit einiger Zeit beantwortet habe. Beim Versuch, meine Antwort zu konstanten Ausdrücken zu verbessern, entdeckte ich einen Leckerbissen zu undefiniertem Verhalten, der mich zu dieser Frage und Antwort führte. Warum haben konstante Ausdrücke einen Ausschluss für undefiniertes Verhalten?.
– Shafik Yaghmour
27. Januar 2014 um 1:37 Uhr