Udostępnij za pośrednictwem


Ostrzeżenie kompilatora (poziom 1) C4838

konwersja z "type_1" na "type_2" wymaga konwersji zawężającej

Wykryto niejawną konwersję zawężającą podczas używania inicjowania agregacji lub listy.

Język C umożliwia niejawne konwersje w przypisań i inicjowania, a język C++ jest zgodny, mimo że nieoczekiwane zawężenie jest przyczyną wielu błędów kodu. Aby kod był bezpieczniejszy, standard C++ wymaga komunikatu diagnostycznego, gdy konwersja zawężająca występuje na liście inicjalizacji. W programie Visual C++diagnostyka to Błąd kompilatora C2397 podczas korzystania z ujednoliconej składni inicjowania obsługiwanej począwszy od programu Visual Studio 2015. Kompilator generuje ostrzeżenie C4838 podczas korzystania z listy lub zagregowanej składni inicjowania obsługiwanej przez program Visual Studio 2013.

Konwersja zawężająca może być w porządku, gdy wiesz, że możliwy zakres przekonwertowanych wartości może mieścić się w obiekcie docelowym. W takim przypadku wiesz więcej niż kompilator. Jeśli celowo dokonasz konwersji zawężającej, intencje będą jawne przy użyciu rzutowania statycznego. W przeciwnym razie ten komunikat ostrzegawczy prawie zawsze wskazuje, że masz usterkę w kodzie. Można to naprawić, upewniając się, że zainicjowane obiekty mają typy, które są wystarczająco duże, aby obsłużyć dane wejściowe.

Poniższy przykład generuje kod C4838 i pokazuje jeden ze sposobów jego naprawy:

// 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
}