Initialisierung eines const int mit einem Fließkomma-Literal

8

Beispiel

%Vor%

Frage

Das Kompilieren des obigen Codes mit g++ -O0 -Wall -pedantic -ansi -std=c++11 ergibt keine Fehler (außer für eine unbenutzte Variable). Wenn ich jedoch -std=c++11 entferne, erhalte ich folgende Warnung:

  

Warnung: ISO C ++ verbietet Array variabler Länge

Nach diese SO Frage glaube ich, dass in C ++ 03, der Code ist ungültig. Kann jedoch jemand erklären, wie sich die Regel in C ++ 11 geändert hat?

(Diese Frage war ein Ergebnis von eine vorherige Frage antwortete ich.)

    
Jesse Good 07.06.2012, 03:56
quelle

1 Antwort

7

Eine Array-Grenze muss ein ganzzahliger konstanter Ausdruck sein, siehe 8.3.4 [dcl.array] / 1 (gleicher Wortlaut in C ++ 03 und C ++ 11):

  

Wenn der Konstanten-Ausdruck (5.19) vorhanden ist, soll er ein ganzzahliger konstanter Ausdruck sein und sein Wert größer als Null sein.

In C ++ 03 kann ein ganzzahliger Konstantenausdruck nicht durch ein Fließkomma-Literal initialisiert werden, es sei denn, er wird in den Ganzzahl-Typ umgewandelt, siehe den letzten Satz von 5.19 [expr.const] / 1:

  

Ein Integralkonstantenausdruck kann nur Literale (2.13), Enumeratoren, const Variablen oder statische Datenelemente von Integral- oder Enumerationstypen enthalten, die mit konstanten Ausdrücken initialisiert sind (8.5), Nicht-Typvorlage Parameter von Integral- oder Enumerationstypen und sizeof -Ausdrücke. Fließende Literale (2.13.3) können nur auftreten, wenn sie in Integral- oder Aufzählungstypen umgewandelt werden.

Dies bedeutet, dass in C ++ 03 i kein Integralkonstantenausdruck ist und daher nicht als Array gebunden verwendet werden kann.

GCC und Clang erlauben Arrays mit variabler Länge als Erweiterung zu C ++ 03, also kompiliert sie mit einer nicht konstanten Grenze, aber Sie erhalten eine Warnung mit -pedantic . Wenn Sie den Initialisierer der Konstanten ändern, um ihn in einen ganzzahligen Typ umzuwandeln, wird i zu einem gültigen Ausdruck für eine ganzzahlige Konstante:

%Vor%

Mit dieser Änderung hat das Array keine variable Länge mehr und es gibt auch keine Warnung mehr mit -pedantic .

In C ++ 11 5.19 [expr.const] / 3 sagt:

  

Ein literaler Konstantenausdruck ist ein Prvalue-Kernkonstantenausdruck des Literaltyps, aber nicht des Zeigertyps. Ein Integralkonstantenausdruck ist ein Literalkonstantenausdruck des Integral- oder Unscoped-Aufzählungstyps.

Die vorhergehenden (ziemlich langen) Absätze beschreiben die Regeln für Kernkonstantenausdrücke, aber im Grunde genommen in C ++ 11 verhindert der Doppelinitialisierer i nicht als Kernkonstantenausdruck, auch ohne eine Umwandlung, also ist es ein Integral konstanter Ausdruck und daher ein gültiges Array gebunden, also keine Warnung.

    
Jonathan Wakely 07.06.2012, 13:41
quelle

Tags und Links