编译器警告(等级 1)C4838

从“type_1”到“type_2”的转换需要收缩转换

使用聚合或列表初始化时发现隐式收缩转换。

C 语言允许在赋值和初始化中进行隐式收缩转换,C++ 也是如此,尽管许多代码错误会导致意外收缩。 为使代码更安全,C++ 标准要求在初始化列表发生收缩转换时提供诊断消息。 在 Visual C++ 中,当使用从 Visual Studio 2015 开始支持的统一初始化语法时,诊断结果为编译器错误 C2397。 使用 Visual Studio 2013 支持的列表或聚合初始化语法时,编译器会生成警告 C4838。

如果你清楚可能范围的转换值适合目标,则可以进行收缩转换。 在这种情况下,你比编译器了解得更多。 如果你有意进行收缩转换,请使用静态强制转换来明确意图。 否则,此错误消息几乎总是指示代码中存在 bug。 确保初始化的对象具有足以处理输入的类型,从而修复此错误。

以下示例生成 C4838 并显示修复它的一种方法:

// C4838.cpp -- C++ narrowing conversion diagnostics
// Compile by using: cl /EHsc C4838.cpp

struct S1 {
    int m1;
    double m2, m3;
};

void function_C4838(double d1) {
    double ad[] = { 1, d1 }; // OK
    int ai[] = { 1, d1 };    // warning C4838
    S1 s11 = { 1, 2, d1 };   // OK
    S1 s12 { d1, 2, 3 };     // warning C4838
    S1 s13 { static_cast<int>(d1), 2, 3 }; // possible fix for C4838
}