用双打的MSVC大括号初始化似乎违反了标准? [英] MSVC brace initialization with doubles appears to violate the standard?

查看:104
本文介绍了用双打的MSVC大括号初始化似乎违反了标准?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

查看以下简单程序:

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 ),仅对未使用的变量发出警告.此外,删除/注释行f4f6会导致编译成功(对于行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 doubledoublefloat或从doublefloat,除非源是常量表达式并且转换后的实际值在可以表示的值的范围内(即使无法准确表示出来)
  • from long double to double or float, or from double to float, 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆