用双打的MSVC大括号初始化似乎违反了标准? [英] MSVC brace initialization with doubles appears to violate the 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
}
使用MSVC 2015使用默认选项(cl /W4
,版本19.00.23918)进行编译时,收到以下消息:
When compiled with MSVC 2015 using the default options (cl /W4
, version 19.00.23918), I get the following messages:
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'
该程序可以使用Clang 3.0-3.8和GCC 4.5.4-6.1.0进行编译(已通过 http://melpon.org/wandbox ),仅对未使用的变量发出警告.此外,删除/注释行f4
和f6
会导致编译成功(对于行f2
仅一个警告).
This program compiles fine with Clang 3.0-3.8 and GCC 4.5.4-6.1.0 (tested with http://melpon.org/wandbox), with only warnings for unused variables. Further, removing/commenting out lines f4
and f6
result in successful compilation (with only the one warning for line f2
).
最初,似乎MSVC只是在告诉我7.2无法精确地表示为float
,因此它的转换范围越来越窄(在括号初始化中是非法的).但是,该标准( N3337草案)第8.5节. 4,注释7这样说:
Initially it looks like MSVC is just telling me that 7.2 can't be represented precisely as a float
, so it's a narrowing conversion (which is illegal in brace initialization). However, the standard (draft N3337), section 8.5.4, note 7, says this:
缩小转换是隐式转换...
A narrowing conversion is an implicit conversion...
- 从
long double
到double
或float
或从double
到float
,除非源是常量表达式并且转换后的实际值在可以表示的值的范围内(即使无法准确表示出来)
- from
long double
todouble
orfloat
, or fromdouble
tofloat
, except where the source is a constant expression and the actual value after conversion is within the range of values that can be represented (even if it cannot be represented exactly)
强调我的.由于7.2在float
可表示的值的范围内,因此根据标准,将其转换为float
不应成为缩小的转换. MSVC在这里出错了吗,我应该提交一个错误吗?
Emphasis mine. Since 7.2 is within the range of values representable by float
, its conversion to float
should not be a narrowing conversion according to the standard. Is MSVC in the wrong here, and should I file a bug?
推荐答案
确实看起来像个错误.要解决此问题,以下内容似乎可以使MSVC 2015中的错误和警告均消失.
It looks like a bug, indeed. For a workaround, the following appears to silence both errors and warnings in MSVC 2015.
#pragma float_control(precise, off, push)
float f2 = 7.2; // OK, with warning
//...
#pragma float_control(precise, pop)
如果使用 /fp:fast
编译器开关,则在全局范围内同样有效,尽管该命令与 /Za
禁用了MS语言扩展
The same works globally if using the /fp:fast
compiler switch, though that one is incompatible with /Za
which disables MS language extensions.
这篇关于用双打的MSVC大括号初始化似乎违反了标准?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!