﻿# 64 бита, /Wp64, Visual Studio 2008, Viva64 и все, все, все\.\.\.

Данная статья ставит своей задачей ответить на ряд вопросов, касающихся безопасного переноса Си/Си\+\+ кода на 64\-битные системы\. Статья написана как ответ на часто обсуждаемую в форумах тематику, связанную с использованием ключа /Wp64 и инструмента Viva64\.


> Среды разработки Visual Studio 2005 и 2008 более не поддерживаются\\\. Вы можете ознакомиться со списком поддерживаемых сред разработки в разделе документации "\[Системные требования анализатора PVS\\\-Studio\]\(https://pvs\-studio\.ru/ru/docs/manual/0018/\)"\\\. Инструмент Viva64 стал частью продукта PVS\\\-Studio и более отдельно не распространяется\\\. Все возможности поиска специфических ошибок, связанных с разработкой 64\\\-битных приложений, а также переносом кода с 32\\\-битной на 64\\\-битную платформу теперь доступны в рамках анализатора \[PVS\\\-Studio\]\(https://pvs\-studio\.ru/ru/pvs\-studio/\)\\\.

## Введение

Я являюсь разработчиком статического анализатора кода Viva64 \[[1](https://pvs-studio.ru/ru/blog/posts/a0009/)\], предназначенного для диагностики ошибок в 64\-битных программах\. Анализатор интегрируется в среду Visual Studio 2005/2008 и позволяет проверить корректность Си/Си\+\+ кода, руководствуясь набором соответствующих правил \[[2](https://pvs-studio.ru/ru/blog/posts/cpp/a0007/)\]\. Потенциально опасные участки кода, обнаруживаемые инструментом Viva64, могут быть своевременно проанализированы и исправлены, что значительно сокращает издержки на тестирование и сопровождение \[[3](https://pvs-studio.ru/ru/blog/posts/cpp/a0006/)\]\.

Общаясь с разработчиками программного обеспечения в форумах, по почте или на конференциях, я заметил, что существует несколько заблуждений, которые приводят к некорректным вопросам, замечаниям и комментариям\. В рамках этой статьи я хочу попробовать пролить свет на эти темные места, связанные с использованием 64\-битных компиляторов, ключа /Wp64 и статического анализатора Viva64\. Для этого я задам несколько обобщенных вопросов и отвечу на них\. Надеюсь, эти ответы помогут лучше Вам ориентироваться в 64\-битных технологиях и правильно подходить к решению задач\.

## 1\. Что такое ключ /Wp64?

Ключ /Wp64 указывает компилятору искать потенциальные ошибки, которые могут возникнуть при компиляции кода для 64\-битных систем\. Проверка заключается в том, что типы, которые отмечены в 32\-битном коде ключевым словом \_\_w64 интерпретируются при проверке как 64\-битные типы\.

Например, пусть мы имеем следующий код:

```cpp
typedef int MyInt32;
#ifdef _WIN64
  typedef __int64 MySSizet;
#else
  typedef int MySSizet;
#endif
void foo() {
  MyInt32 value32 = 10;
  MySSizet size = 20;
  value32 = size;
}
```

Выражение "value32 \= size;" на 64\-битной системе приведет к урезанию значения, а следовательно к потенциальной ошибке\. Мы хотим это диагностировать\. Но при компиляции 32\-битного приложения, все корректно и мы не получим предупреждения\.

Чтобы подготовиться к 64\-битным системам нам следует добавить ключ /Wp64 и вставить ключевое слово \_\_w64 при описании типа MySSizet в 32\-битном варианте\. В результате код станет выглядеть так:

```cpp
typedef int MyInt32;
#ifdef _WIN64
  typedef __int64 MySSizet;
#else
  typedef int __w64 MySSizet; // Add __w64 keyword
#endif
void foo() {
  MyInt32 value32 = 10;
  MySSizet size = 20;
  value32 = size; // C4244 64-bit int assigned to 32-bit int
}
```

Теперь мы получим предупреждение C4244, которое поможет подготовиться к переносу кода на 64\-битную платформу\.

Обратите внимание, что для 64\-битного режима компиляции ключ /Wp64 значения не имеет, так как все типы уже имеют необходимый размер и компилятор произведет необходимые проверки\. То есть при компиляции 64\-битной версии даже с выключенным ключом /Wp64 мы получим предупреждение C4244\.

Поэтому, если Вы регулярно компилируете свой код в 64\-битном режиме, то Вы вполне можете отказаться от использования /Wp64 в 32\-битном коде, поскольку в 64\-битном режиме проверка производится более полно\. Кроме того, система диагностики с ключом /Wp64 не совершенна и часто приводит к ложным срабатываниям или, наоборот, к замалчиванию предупреждений\. Более подробно с этой проблемой Вы можете познакомиться по следующим ссылкам \[[4](https://social.msdn.microsoft.com/Forums/vstudio/en-US/49112cc5-6198-4597-9a22-7855aeaa163f/warning-c4267-with-stdvector?forum=vclanguage)\]\.

## 2\. Зачем нужен анализатор Viva64, если есть /Wp64?

Этот вопрос является одним из наиболее часто задаваемых, но, по сути, он некорректен\. Вначале приведем аналогию\. Современные компиляторы языка Си/Си\+\+ выдают большое количество сообщений, предупреждающих о потенциальных ошибках\. Но это совершенно не уменьшает актуальность существования и использования таких инструментов как lint, Gimpel PC\-Lint, Parasoft C\+\+Test или Abraxas CodeCheck\. И никто не ставит вопрос, зачем нужны эти анализаторы, если в компиляторе Visual C\+\+, есть ключ /W4 или /Wall\.

Задача компилятора состоит в обнаружении синтаксических ошибок в программах и выдачи предупреждений на основные типовые потенциальные ошибки\. Ограничение на подробность диагностики потенциально опасных конструкций связано с необходимостью выбора разумного подмножества диагностик, с большой вероятностью полезных всем программистам\. Другой причиной являются требования к производительности компилятора\. Некоторые проверки требуют достаточно много времени, но совершенно могут быть не востребованы многими программистами\.

Статические анализаторы общего назначения позволяют диагностировать обширные классы потенциальных ошибок и плохой стиль кодирования\. В общем, все то, что отсутствует в компиляторе\. Настройки статического анализатора затачиваются под конкретные задачи и подробно выводят информацию по интересующим разработчика ошибкам\. Статические анализаторы хотя и запускаются регулярно, но не при компиляции каждого файла в процессе разработки\. Это позволяет выполнять достаточно глубокий анализ, требующий дополнительных затрат времени\. Статический анализ занимает достойное место среди других методологий повышения качества и надежности кода\.

Похожая ситуация и с проверкой совместимости кода с 64\-битными системами\. Мы уже кратко рассмотрели, что дает ключ /Wp64\. Этот ключ является хорошим подспорьем программисту, но помощь следует ждать от него только в ограниченном наборе случаев\. К сожалению, типовых ошибок связанных с использованием 64\-битных систем гораздо больше\. Эти типовые ошибки подробно описаны в статье "20 ловушек переноса Си\+\+ \- кода на 64\-битную платформу" \[[5](https://pvs-studio.ru/ru/blog/posts/cpp/a0004/)\], с которой я прошу обязательно познакомиться\. Именно из\-за большой разницы в количестве проверок, предоставляемых /Wp64, и необходимого количества проверок возникает потребность в специализированном инструменте\. Таким специализированным инструментов и является Viva64\.

Задают еще один попутный вопрос: "Некоторые анализаторы, такие как Gimpel PC\-Lint или Parasoft C\+\+Test, также заявляют о поддержке диагностики 64\-битных ошибок\. Зачем тогда еще один \- Viva64?"\. Да, заявляют и поддерживают\. Но, во\-первых, менее подробно\. Например, не учитывается ряд ошибок, связанных с особенностями современного языка Си\+\+\. А во\-вторых, эти анализаторы ориентированы на модели данных Unix\-систем и плохо подходят для анализа 64\-битных программ разрабатываемых в среде Visual Studio\. Более подробно обо всем этом можно почитать в статье "Забытые проблемы разработки 64\-битных программ" \[[6](https://pvs-studio.ru/ru/blog/posts/cpp/a0010/)\]\.

Вывод: наличие ключа /Wp64 и других статических анализаторов, никак не уменьшает актуальность использования Viva64\.

## 3\. Почему в Visual Studio 2008 ключ /Wp64 объявлен устаревшим?

Есть ошибочное мнение о том, что /Wp64 объявлен устаревшим по причине, что диагностика 64\-битных ошибок в Visual Studio 2008 стала намного лучше\. Нет, это не так\.

Ключ /Wp64 в Visual Studio 2008 объявлен устаревшим по той простой причине, что он больше не нужен\. Прошло время "готовиться к 64\-битному коду", пора уже создавать 64\-битные программы\. А для этого в Visual Studio 2008, да и в Visual Studio 2005 есть 64\-битный компилятор\.

Ключ /Wp64 полезен только в режиме компиляции 32\-битных программ\. Он был создан для того, чтобы заранее увидеть ряд проблем, с которыми программа столкнется в будущем на 64\-битных системах\.

При компиляции 64\-битной программы ключ /Wp64 не имеет смысла\. Компилятор 64\-битных приложений автоматически делает проверки, аналогичные /Wp64, но более аккуратно\. При компиляции 32\-битных программ режим /Wp64 иногда давал сбои, что приводило к ложным предупреждениям\. Это не очень приятно и многие разработчики жаловались на это и просили доработать данный режим компилятора\. Разработчики Visual C\+\+ поступили, на мой взгляд, очень разумно\. Вместо того, чтобы тратить время на доработку /Wp64 они объявляют его устаревшим\. Тем самым они:

* дополнительно стимулируют программистов компилировать свои программы 64\-битным компилятором;
* упрощают и без того перегруженную систему команд компилятора, убирая временный вспомогательный ключ;
* устраняют просьбы по доработке данного ключа\.

## 4\. Актуален ли инструмент Viva64 при переходе на Visual Studio 2008?

Да, актуален\. Ничего ведь не изменилось\. Никаких новых существенных изменений компилятор в плане создания 64\-битных программ не претерпел\. В 32\-битном компиляторе ключ /Wp64 объявили устаревшим, чтобы стимулировать переход на 64\-битные системы, но к Viva64 это никакого отношения не имеет\. Анализатор Viva64 обнаруживает намного больше потенциальных "64\-битных" ошибок, чем 64\-битный компилятор Visual C\+\+ 2005/2008 и успешно используется многими разработчиками\.

Напоследок хочу еще раз уделить немного времени борьбе с Евангелистами, которые проповедуют, что компилятор способен диагностировать все 64\-битные ошибки и отказ от /Wp64 тому подтверждение\.

Прошу, перечитайте еще раз статью "20 ловушек переноса Си\+\+ \- кода на 64\-битную платформу" \[[5](https://pvs-studio.ru/ru/blog/posts/cpp/a0004/)\]\. Прошу \- ЗАДУМАЙТЕСЬ\!

Не может, не может компилятор выдавать предупреждения на конструкции вида:

```cpp
unsigned i;
size_t size;
for (i = 0; i != size; i++)
...
```

Или, например:

```cpp
int x, y, z, w, h;
int position = x + y * w + z * w * h;
bigArray[position] = 0.0f;
```

Это канонические, широко используемые конструкции\. Чаще всего они безопасны\. И разработчики компиляторов не внесут предупреждения на подобные конструкции, хотя при переходе на 64\-битные системы они несут потенциальную опасность\! И их следует хотя бы один раз проанализировать\. Такие ошибки трудно обнаружимы и проявляются только на больших массивах данных или при обработке большого количества элементов\.

Но все эти проблемы легко можно обнаружить, просматривая код с использованием Viva64\. Прошу, не обманывайте разработчиков, убеждая, что в их программах все хорошо\. Вы не сделаете им этим лучше\. Но легко можете спровоцировать осуществить переход на 64\-битную системы небрежно и тем самым посеять несколько редких ошибок, которые выявятся уже на этапе эксплуатации\.

## Выводы

1. Ключ /Wp64 полезен, но вовсе не достаточен, чтобы гарантировать работоспособность 64\-битной программы\.
1. Для более тщательного анализа 64\-битного кода следует использовать статические анализаторы, реализующие соответствующие проверки\.
1. Для проверки Си/Си\+\+ кода для 64\-битной операционный системы Windows лучшим решением является специализированный инструмент Viva64\.

## Библиографический список

1. Евгений Рыжков\. [Viva64: что это и для кого?](https://pvs-studio.ru/ru/blog/posts/a0009/) 
1. Андрей Карпов, Евгений Рыжков\. [Статический анализ кода для верификации 64\-битных приложений\.](https://pvs-studio.ru/ru/blog/posts/cpp/a0007/) 
1. Андрей Карпов\. [Проблемы тестирования 64\-битных приложений\.](https://pvs-studio.ru/ru/blog/posts/cpp/a0006/)
1. MSDN Forum, "[warning C4267 with std::vector](https://social.msdn.microsoft.com/Forums/vstudio/en-US/49112cc5-6198-4597-9a22-7855aeaa163f/warning-c4267-with-stdvector?forum=vclanguage)"\.
1. Андрей Карпов, Евгений Рыжков\. [20 ловушек переноса Си\+\+ \- кода на 64\-битную платформу\.](https://pvs-studio.ru/ru/blog/posts/cpp/a0004/) 
1. Андрей Карпов\. [Забытые проблемы разработки 64\-битных программ\.](https://pvs-studio.ru/ru/blog/posts/cpp/a0010/)