c++ - 为什么没有检测到这种缩小转换?

标签 c++ visual-studio c++11 list-initialization

使用列表初始化构造变量时(如 int x{ 5 };)the standard §8.5.4 说:

If a narrowing conversion […] is required to convert any of the arguments, the program is ill-formed. (7) A narrowing conversion is an implicit conversion - (7.4) from an integer type or unscoped enumeration type to an integer type that cannot represent all the values of the original type, except where the source is a constant expression whose value after integral promotions will fit into the target type.

那么为什么会编译呢?

char c{ 'A' };
char x{ c + c };

提醒一下,c + c 产生一个 int

static_assert(std::is_same_v<decltype(c + c), int>, "");

所以编译器应该提示缩小转换肯定不是一个常量表达式。


有趣的是,正确地将 x 声明为 unsigned char 无法编译:

char c{ 'A' };
unsigned char x{ c + c }; 

C2397 conversion from 'int' to 'unsigned char' requires a narrowing conversion

就像引入一个临时的一样:

char c{ 'A' };
int sum{ c + c };
char x{ sum }; //C2397 conversion from 'int' to 'char' requires [...]

那么为什么第一个版本可以编译?我正在使用 Visual Studio Community 2017 版本 15.9.5 并使用 /wall 进行编译,所有警告都是在 x64 调试版本中启用的错误。设置标准的 C++11、C++14 和 C++17 都可以编译。


我提交了错误报告 here

最佳答案

是的。你是对的:程序是格式错误的

在这种情况下(标准 §1.4):

a conforming implementation shall issue at least one diagnostic message.

确实,gcc 会产生警告消息。 clang 直接将代码拒绝为编译器错误。

这个特定的话题已经讨论过了here对于 gcc1.

Visual Studio 应该会生成一条诊断消息(我建议您检查您的编译选项。您是否禁用了警告?您是否使用 C++(11/14/17) 进行编译?, ...)。如果不是这种情况,那就是实现错误。

更新:

Visual Studio v19.20不会产生任何诊断消息(即使带有 /Wall 标志)。

A bug report这里已经填好了。


1 有关 gcc 实现以进行缩小检查的更多信息 here .

关于c++ - 为什么没有检测到这种缩小转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56665797/

相关文章:

c++ - Windows 函数 "GetCursorInfo"返回成功但光标的 HANDLE 为 NULL

c++ - 了解工厂方法和静态变量分配的返回值优化 (Visual Studio)

c++ - 有没有办法将原始 MPU-6050 数据转换为 0-359 旋转数据

c++ - 如何在 MSVS 中为 Windows XP 编译 C++ 应用程序?

linux - 获取未编译项目的智能感知数据

visual-studio-2010 - PostBuildEvent 多脚本错误处理

c++ - 如何使法语键盘的点键(数字键盘)用作 Qt 的输入?

c++ - 插入无序映射调用构造函数

具有默认参数的函数的 C++ 偏序

c++ - 从 Map 删除后访问指针