8

Warum funktioniert der Compiler (Klirren, gcc) nicht über eingrenzende Konvertierungen warnen, wenn dieseSchwimmer Initialisierung von Doppel mit Klammern

float a{3.1231231241234123512354123512341235123541235}; 
float a = {double(3.1231231241234123512354123512341235123541235)} 

tun ich eine Warnung zu erwarten, weil ich mit Klammern expliziten Wert-Initialisierung tun. Nach dieser Antwort Link sollte es einen Fehler ausspucken.

Compilation here

+3

afaik, es warnt Sie nicht, wenn ein bestimmter Literalwert in einem schmaleren Typ ohne Präzisionsverlust dargestellt werden kann –

+0

Dies kompiliert nicht auf VS2015 (Fehler 2397) – Fefux

Antwort

15

[dcl.init.list]/§7 (Normentwurf)

eine Verengung Umwandlung ist eine implizite Umwandlung

...

  • von long double zu verdoppeln oder zu schwimmen, oder von doppelt zu schweben, außer wenn die Quelle ein konstanter Ausdruck, und die tatsächlichen Wert nach der Umwandlung im Bereich von Werten, die (auch wenn es nicht genau dargestellt werden kann) oder

...

dargestellt werden können

Beide Ausdrücke 3.14159 und double(3.141) sind konstante Ausdrücke und der Wert liegt im Bereich von Werten darstellbaren float.Daher ist die Umwandlung nicht , die wie durch den Standard definiert verengt und es gibt keine Anforderung, über die Umwandlung zu warnen.


aber es gibt nicht eine Warnung auch für längere Eingänge

Sure it does, solange der Wert außerhalb des Wertebereichs liegt darstellbaren float.

10

Da die Quelle ist ein konstanter Ausdruck und Überlauf für diese Fälle nicht auftritt, dann narrowing conversion Fehler nicht ausgelöst werden.

(emphasis Mine)

Umwandlung von einer langen Doppel von Doppel zu verdoppeln oder zu schweben und die Umwandlung zu schweben, außer wenn die Quelle ein konstanter Ausdruck ist, und Überlauf nicht auftritt

Wenn Sie es mit einer double Variablen (dh einem nicht konstanten Ausdruck) oder einer Konstanten mit einem großen Wert verwenden, der zu einem Überlauf führt, wird die Diagnosemeldung generiert. z.B.

double d = 3.14159; 
float a {d}; // non-constant-expression cannot be narrowed from type 'double' to 'float' in initializer list 

EDIT (für längeren Eingang)

Denn auch wenn der Wert nicht genau durch float dargestellt werden, Überlauf immer noch nicht auftreten, dann ist es erlaubt.

$8.6.4/7.2 List-initialization (emphasie Mine)

von long double zu verdoppeln oder zu schweben, oder von doppelt zu schweben, mit der Ausnahme, wo die Quelle ein konstanter Ausdruck ist, und der Ist-Wert nach der Umwandlung innerhalb des Bereichs von Werten ist das kann dargestellt werden (auch wenn sie nicht genau dargestellt werden kann) oder

+1

Wenn Sie sagen, ** sollte ein Fehler sein, nicht ein Warnung **, würde ich klarstellen, dass der Standard kein Fehler sein muss. – user2079303

+0

@ user2079303 Der Standard sagt "solche Konvertierungen sind nicht erlaubt", also denke ich, Warnung ist nicht der Fall, nicht wahr? – songyuanyao

+0

Sie sind richtig, aber es gibt keine Warnung auch für längere Eingaben – Gabriel

Verwandte Themen