C4311 и C4312 – это одни из распространенных предупреждений, генерируемых компилятором для 32-битного кода, не адаптированного для переноса на 64-разрядные платформы. Они выводятся только в случае использования параметра /Wp64 (выявление проблем переносимости на 64-разрядные платформы), предназначенного для подготовки миграции приложений на 64-битные системы.
Заметим, что начиная с Visual C++ 9.0 параметр /Wp64 объявлен устаревшим, поскольку время "готовиться к 64-битному коду" уже прошло.
Предупреждения C4311 и C4312 сообщают о попытке поместить указатель в 32-разрядную переменную или наоборот. В 64-битной системе эти преобразования некорректны. Если код скомпилирован на 64-разрядной платформе, значение указателя (64 разряда) будет усечено, если оно присваивается переменной типа int (32 разряда). Пример кода, вызывающего предупреждение C4311 и C4312:
int *p;
int a = (int)p; //C4311
p = (int *)a; //C4312
Исправление кода заключается в использовании memsize-типов, способных хранить в себе указатель, например size_t, ptrdiff_t, intptr_t, LONG_PTR и так далее. Пример корректного кода:
int *p;
INT_PTR b = (INT_PTR)p; //OK
Подробные рекомендации по созданию безопасного 64-битного кода даны в курсе "Разработка 64-битных приложений на языке Си/Си++".
Если разрабатываемая программа имеет короткий жизненный цикл и не планируется её портирование на 64-битную платформу, данные предупреждения могут быть устранены путём отключения в настройках компилятора параметра /Wp64.
Следует отметить, что ключ /Wp64 осуществляет достаточно поверхностный анализ и выявляет только наиболее грубые ошибки. Для полноценной проверки кода мы предлагаем использовать специализированный статический анализатор кода Viva64, входящий в пакет PVS-Studio. Со сравнением диагностических возможностей Visual C++ и Viva64 можно ознакомиться в статье "Сравнение возможностей PVS-Studio и Visual Studio 2010 по выявлению дефектов в 64-битных программах".
0