コンパイラの警告 (レベル 1) C4838

'type_1' から 'type_2' への変換には縮小変換が必要です

集約またはリスト初期化を使用するときに、暗黙的な縮小変換が見つかりました。

C 言語では、割り当てと初期化で暗黙的な縮小変換が可能であり、予期しない縮小は多くのコード エラーの原因ですが、C++ はそれに従います。 コードをより安全にするために、C++ 標準では、縮小変換が初期化リストで発生した場合に診断メッセージが必要です。 Visual C++ では、Visual Studio 2015 以降でサポートされている一様な初期化構文を使用すると、診断はコンパイラ エラー C2397 になります。 Visual Studio 2013 でサポートされているリストまたは集計の初期化構文を使用すると、コンパイラで警告 C4838 が生成されます。

縮小変換は、変換された値の可能な範囲がターゲットに収まることがわかっている場合に問題ありません。 この場合は、ユーザーがコンパイラよりも多くを知っているということです。 縮小変換を意図的に行う場合は、静的キャストを使用して意図を明示的にします。 それ以外の場合、この警告メッセージは、ほとんど常にコードにバグがあることを示しています。 解決するには、初期化するオブジェクトに入力を処理するのに十分な大きな型が含まれていることを確認します。

次の例では、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
}