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

huangapple go评论107阅读模式
英文:

Visual Studio 2019 compiler error C2397 and warning C4838: narrowing conversion diagnostic

问题

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

conversion from 'T' to 'size_t' requires a narrowing conversion.

与此相反,下面的代码会产生警告:

(level 1) C4838: "conversion from 'T' to 'size_t' requires a narrowing conversion".

我觉得这种行为不一致。我理解存在一个缩窄转换,C++标准要求生成诊断消息,但是第一个示例和第二个示例之间有何不同,使得第一个是错误,而第二个只是警告?

英文:

In Visual Studio 2019 the following code produces the compiler error 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 };    

In contrast, the code below produces the warning

(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 };    

I find this behavior inconsistent. I understand that there is a narrowing conversion and C++ standard requires a diagnostic message, but what is so different between these examples such that the first one is an error, whereas the second is just a warning?

答案1

得分: 1

这是为了向后兼容而进行的不同行为。

T t{v} 在 C++11 之前是无效的代码。
T t = {v} 在 C++11 之前是有效的代码,并且可能会产生关于缩小转换的警告。

T t{v} 从 C++11 开始是有效的代码,可能会产生缩小转换的错误。这是符合标准 C++11 的新行为。它不会破坏旧代码,因为这是一种新的初始化语法。

关于T t = {v} 中的缩小转换警告是为了向后兼容而保留的。否则,如果将它与 C++11 编译器一起编译,它会破坏先前成功编译的 C++98 代码。

英文:

This is a different behavior for backward compatibilty.

T t{v} is an invalid code until C++11.
T t = {v} is a valid code until C++11 and can produce the warning about a narrowing conversation.

T t{v} is a valid code since C++11 and can produce an error of a narrowing conversion. It's a new behavior conforming to the standard C++11. It can't break an old code, because this a new initialization syntax.

The warning about a narrowing conversation in T t = {v} is kept for backward compatibilty. Otherwise it would break previously compiled successfully C++98 code if it's compiled with a C++11 compiler.

huangapple
  • 本文由 发表于 2023年4月4日 15:19:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/75926529.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定