为什么未检测到这种缩小的转换?

Sta*_*nny 15 c++ visual-studio c++11 list-initialization

使用列表初始化(如int x{ 5 };)构造变量时,标准 §8.5.4表示:

如果需要缩小转换[…]来转换任何参数,则程序格式错误。 (7)缩小转换是隐式转换- (7.4)从整数类型或无作用域枚举类型到不能表示原始类型的所有值的整数类型,除非源是一个常数表达式,其值在整数提升后将适合目标类型。

那么为什么要编译呢?

char c{ 'A' };
char x{ c + c };
Run Code Online (Sandbox Code Playgroud)

作为提醒,c + c产生一个int

static_assert(std::is_same_v<decltype(c + c), int>, "");
Run Code Online (Sandbox Code Playgroud)

因此,编译器应该抱怨转换变窄,这肯定不是常量表达式。


有趣的是,声明xunsigned char正确编译失败:

char c{ 'A' };
unsigned char x{ c + c }; 
Run Code Online (Sandbox Code Playgroud)

C2397从'int'到'unsigned char'的转换需要缩小的转换

就像介绍临时文件一样:

char c{ 'A' };
int sum{ c + c };
char x{ sum }; //C2397 conversion from 'int' to 'char' requires [...]
Run Code Online (Sandbox Code Playgroud)

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


我在这里提交了错误报告

Bia*_*sta 11

是。您说对了:程序格式错误

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

合格的实施应发出至少一个诊断消息。

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

这里已经针对gcc 1讨论了这个特定主题。

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

更新:

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

错误报告已在此处填写。


1 有关此处的 gcc缩窄检查实施的其他信息。