Предупреждение компилятора (уровень 1) C4838
Преобразование из "type_1" в "type_2" требует сужения преобразования
Неявное сужение преобразования было найдено при использовании статистической или инициализации списка.
Язык C позволяет неявно сужать преобразования в назначениях и инициализации, и C++ следует примеру, несмотря на то, что неожиданное сужение является причиной многих ошибок кода. Чтобы сделать код более безопасным, стандарт C++ требует диагностического сообщения, когда сужающее преобразование происходит в списке инициализации. В Visual C++диагностика — ошибка компилятора C2397 при использовании синтаксиса универсальной инициализации, поддерживаемого начиная с Visual Studio 2015. Компилятор создает предупреждение C4838 при использовании синтаксиса инициализации списка или статистической инициализации, поддерживаемого Visual Studio 2013.
Сужающее преобразование может быть в порядке, если вы знаете возможный диапазон преобразованных значений, которые могут соответствовать целевому объекту. В этом случае вы знаете больше, чем компилятор. Если вы делаете сужающее преобразование намеренно, сделайте свои намерения явными с помощью статического приведения. В противном случае это предупреждение почти всегда указывает на наличие ошибки в коде. Это можно исправить, убедившись, что объекты, инициализируемые, имеют достаточно большие типы для обработки входных данных.
Следующий пример создает 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
}