2016-07-08 34 views
10

Dai un'occhiata a questo semplice programma:L'inizializzazione del bridging MSVC con il doppio sembra violare lo standard?

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 
} 

quando si compila con MSVC 2015 utilizzando le opzioni di default (cl /W4, versione 19.00.23918), ottengo i seguenti messaggi:

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' 

Questo programma compila bene con Clang 3.0-3.8 e GCC 4.5.4-6.1.0 (testato con http://melpon.org/wandbox), con solo avvisi per le variabili non utilizzate. Inoltre, la rimozione/commento delle righe f4 e f6 ha esito positivo nella compilazione (con solo un avviso per la riga f2).

Inizialmente sembra che MSVC mi stia semplicemente dicendo che 7.2 non può essere rappresentato precisamente come float, quindi è una conversione di restringimento (che è illegale nell'inizializzazione delle parentesi). Tuttavia, lo standard (draft N3337), sezione 8.5.4, nota 7, dice questo:

Un restringendo la conversione è una conversione implicita ...

  • long double-double o float, oppure da double a float, tranne quando la sorgente è un'espressione costante e il valore effettivo dopo la conversione rientra nell'intervallo di valori che può essere rappresentato (anche se non può essere rappresentato esattamente)

Enfasi mia. Poiché 7.2 è compreso nell'intervallo di valori rappresentabile da float, la sua conversione in float non deve essere una conversione di restringimento in base allo standard. MSVC ha torto qui e dovrei presentare un bug?

+0

Imo 2015 è andato in mare con avvisi restringimento di conversione, quindi sì si prega di inviare una segnalazione di bug :) –

+0

Oh, sono per lo più fresco con avvertimenti. Sono gli errori che non sopporto.Il mio codebase ha un sacco di float e doppie costanti (yay per il codice matematico), quindi trovare solo le costanti float per aggiungere "f" a ciascuna sarà molto, molto fastidioso. – nneonneo

+0

Prova anche con '/ W4' per favore. –

risposta

6

Sembra un bug, davvero. Per risolvere il problema, il seguente sembra tacere entrambi gli errori e gli avvisi in MSVC 2015.

#pragma float_control(precise, off, push) 

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

#pragma float_control(precise, pop) 

Le stesse opere a livello globale se si utilizza l'interruttore /fp:fast compilatore, anche se quello è incompatibile con /Za che disabilita estensioni del linguaggio MS.

+1

Oh, bella nota sul pragma 'float_control' - non lo sapevo! – nneonneo

-3

Alcuni numeri in virgola mobile possono essere espressi esattamente in una rappresentazione float e altri no. Se il numero può essere rappresentato nel modulo x/2^y dove x è un numero intero e è un numero intero 23 o inferiore, si adatta. La maggior parte dei numeri decimali non può essere rappresentata in questo modo, come un numero binario che ripetono per sempre. 7.2 è un esempio.

È possibile risolvere facilmente questo problema aggiungendo f a ciascun numero, per indicare al compilatore che si tratta di una costante float anziché double.

float f4{ 7.2f }; 
+2

Non valido motivo per rifiutare il codice, vedere la citazione standard sopra o 8.5.4/7 in N4141. –

+0

@BaummitAugen potrebbe non essere un valido motivo, ma finché c'è un compilatore là fuori che genera questo errore ci dovrebbe essere una spiegazione per abbinarlo. E certamente la correzione che do funziona perfettamente. –

+0

L'osservazione che 7.2 non può essere rappresentato esattamente è già parte della domanda e della citazione standard. – Anedar

Problemi correlati