Inicialização de chaves MSVC com duplas parece violar o padrão?
Confira este programa simples:
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 compilado com o MSVC 2015 usando as opções padrão (cl /W4
, versão 19.00.23918), recebo as seguintes mensagens:
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'
Este programa compila bem com o Clang 3.0-3.8 e o GCC 4.5.4-6.1.0 (testado comhttp://melpon.org/wandbox), com apenas avisos para variáveis não utilizadas. Além disso, remover / comentar linhasf4
ef6
resultar em compilação bem-sucedida (com apenas um aviso para linhaf2
)
Inicialmente, parece que o MSVC está me dizendo que o 7.2 não pode ser representado precisamente como umfloat
, portanto, é uma conversão restritiva (que é ilegal na inicialização entre parênteses). No entanto, o padrão (projecto N3337), seção 8.5.4, nota 7, diz o seguinte:
A restrição de conversão é uma conversão implícita ...
delong double
paradouble
oufloat
ou dedouble
parafloat
, exceto onde a origem é uma expressão constante e o valor real após a conversão está dentro do intervalo de valores que podem ser representados (mesmo que não possa ser representado exatamente)Ênfase minha. Como 7.2 está dentro da faixa de valores representáveis porfloat
, sua conversão parafloat
não deve ser uma conversão restritiva de acordo com o padrão. O MSVC está errado aqui e devo registrar um erro?