Visual Studio 2019编译错误C2397和警告C4838:缩小转换诊断



在Visual Studio 2019中,以下代码产生编译器错误C2397:

conversion from 'T' to 'size_t' requires a narrowing conversion.
struct Narrow
{
template <typename T>
Narrow(T t)
: szt{ t }
{ }
std::size_t szt[1];
};
Narrow narrow{ 3 };    

相反,下面的代码产生警告

(level 1) C4838: "conversion from 'T' to 'size_t' requires a narrowing conversion".
struct Narrow
{
template <typename T>
Narrow(T t)
{
std::size_t arr[] { t };
}
};
Narrow narrow{ 3 };    

我发现这种行为不一致。我知道有一个缩小的转换和c++标准需要一个诊断消息,但是这两个例子之间有什么不同,以至于第一个是错误,而第二个只是一个警告?

这是一种不同的向后兼容行为。

T t{v}在c++ 11之前是无效代码。T t = {v}在c++ 11之前是一个有效的代码,并且可以产生关于缩小对话的警告。

T t{v}自c++ 11以来是一个有效的代码,可以产生窄化转换的错误。这是一个符合标准c++ 11的新行为。它不能破坏旧的代码,因为这是一个新的初始化语法。

关于T t = {v}中缩小对话的警告是为了向后兼容而保留的。否则,如果使用c++ 11编译器编译,则会破坏先前已成功编译的c++ 98代码。

最新更新