2016-07-08 2 views
10

Überprüfen Sie dieses einfache Programm aus:MSVC Klammerinitialisierung mit Doppelgänger scheint den Standard zu verletzen?

int main() { 
    float f2 = 7.2; // OK, with warning 
    float f3 = 7.199999809265137; // OK, no warning 
    float f4{ 7.2 }; // Fails 
    float f5{ 7.199999809265137 }; // OK, no warning 
    float f6 = { 7.2 }; // Fails 
    float f7 = { 7.199999809265137 }; // OK, no warning 
} 

Wenn mit MSVC 2015 mit den Standardoptionen zusammengestellt (cl /W4, Version 19.00.23918), erhalte ich folgende Meldungen:

FloatTest.cpp(2): warning C4305: 'initializing': truncation from 'double' to 'float' 
FloatTest.cpp(4): error C2397: conversion from 'double' to 'float' requires a narrowing conversion 
FloatTest.cpp(4): warning C4305: 'initializing': truncation from 'double' to 'float' 
FloatTest.cpp(6): error C2397: conversion from 'double' to 'float' requires a narrowing conversion 
FloatTest.cpp(6): warning C4305: 'initializing': truncation from 'double' to 'float' 

Dieses Programm fein kompiliert mit Clang 3.0-3.8 und GCC 4.5.4-6.1.0 (getestet mit http://melpon.org/wandbox), mit Warnungen nur für unbenutzte Variablen. Außerdem führen das Entfernen/Kommentieren der Zeilen f4 und f6 zu einer erfolgreichen Kompilierung (mit nur einer Warnung für Zeile f2).

Am Anfang sieht es so aus, als ob MSVC mir gerade sagt, dass 7.2 nicht genau als float dargestellt werden kann, also ist es eine einschränkende Umwandlung (was bei der Klammerinitialisierung illegal ist). Allerdings ist die Norm (draft N3337), Abschnitt 8.5.4, Anmerkung 7, sagt dieser:

A verengenden Umwandlung ist eine implizite Konvertierung ...

  • long double-double oder float, oder von double bis float, außer wenn die Quelle ein konstanter Ausdruck ist und der tatsächliche Wert nach der Konvertierung innerhalb des Wertebereichs liegt, der dargestellt werden kann (, auch wenn er nicht exakt dargestellt werden kann)

Schwerpunkt meiner. Da 7.2 innerhalb des Wertebereichs liegt, der durch float darstellbar ist, sollte seine Umwandlung in float keine verkleinerte Umwandlung gemäß dem Standard sein. Ist MSVC hier falsch, und sollte ich einen Fehler einreichen?

+0

Imo 2015 ging mit der Verengung-Konvertierung Warnungen über Bord, also bitte bitte einen Fehlerbericht :) –

+0

Oh, ich bin meistens cool mit Warnungen. Es sind die Fehler, die ich nicht ertragen kann.Meine Codebasis hat eine Tonne von float und double Konstanten (yay für math code), also wird es sehr, sehr ärgerlich sein, nur die float Konstanten zu finden, die "f" an jedes einzelne anhängen. – nneonneo

+0

Versuchen Sie bitte mit '/ W4'. –

Antwort

6

Es sieht tatsächlich wie ein Fehler aus. Für dieses Problem zu umgehen, wird die folgende beiden Fehler und Warnungen in MSVC 2015.

#pragma float_control(precise, off, push) 

float f2 = 7.2; // OK, with warning 
//... 

#pragma float_control(precise, pop) 

Das gleiche funktioniert global zum Schweigen zu bringen, wenn mit dem /fp:fast Compiler-Schalter, wenn auch, dass man mit /Za unvereinbar ist, die MS Spracherweiterungen deaktiviert.

+1

Oh, nette Anmerkung zum 'float_control' Pragma - das wusste ich nicht! – nneonneo

-3

Einige Fließkommazahlen können in einer float Darstellung genau ausgedrückt werden und einige nicht. Wenn die Zahl in der Form dargestellt werden kann, wobei x eine ganze Zahl ist und y eine ganze Zahl von 23 oder weniger ist, passt sie. Die meisten Dezimalzahlen können nicht auf diese Weise dargestellt werden, da sie sich als Binärzahl für immer wiederholen. 7.2 ist ein Beispiel.

Sie können dies leicht beheben, indem Sie an jede Zahl f anhängen, um dem Compiler anzuzeigen, dass dies eine float Konstante ist, anstatt eine double.

float f4{ 7.2f }; 
+2

Kein gültiger Grund, den Code abzulehnen, siehe das Standardzitat oben oder 8.5.4/7 in N4141. –

+0

@BaummitAugen es möglicherweise kein gültiger Grund, aber solange es einen Compiler gibt, der diesen Fehler erzeugt, sollte es eine Erklärung geben, um es zu entsprechen. Und die Reparatur, die ich gebe, funktioniert perfekt. –

+0

Die Beobachtung, dass 7.2 nicht exakt dargestellt werden kann, ist bereits Teil der Frage und des Standardzitats. – Anedar

Verwandte Themen