﻿# C\+\+Builder, сборка 64\-битных приложений и ренессанс Viva64

После долгих ожиданий в C\+\+Builder XE3 Update 1 появилась возможность сборки 64\-битных приложений\. Это значит, что использующим этот инструмент разработчикам предстоит скоро столкнуться с незнакомым для них миром 64\-битных ошибок\. 


> Поддержка C\\\+\\\+ Builder была прекращена в PVS\\\-Studio после версии 5\\\.20\\\. По всем возникшим вопросам вы можете обратиться в нашу \[поддержку\]\(https://pvs\-studio\.ru/ru/about\-feedback/\)\\\.

## Что такое 64\-битная ошибки?

Это самая обыкновенная ошибка в программе\. Но у неё есть особенность\. Она проявляет себя только в 64\-битных программах \[[1](https://pvs-studio.ru/ru/blog/terms/0002/)\]\. В тоже время, собрав 32\-битную версию программы, вы не обнаружите эту ошибку\. Продемонстрируем в начале самый простой пример:

```cpp
float *buf = (float *)malloc(1000 * sizeof(float));
unsigned X = (unsigned)buf;
...
float *p = (float *)X;
```

Указатель какое\-то время хранится в переменной типа unsigned\. В 64\-битной программе указатель станет 64\-битным, а тип unsigned по\-прежнему состоит из 32 бит\. В результате будут потеряны старшие биты, и последствия работы программы станут непредсказуемы\. Дополнительно такая ошибка коварна тем, что будет редко проявлять себя в 64\-битной программе\. Беда произойдет только тогда, когда память будет выделена за пределами первых 4 гигабайт адресного пространства\.

Показанная выше 64\-битная ошибка проста и не интересна\. Любой компилятор предупредит о подобном опасном приведении типов\. Рассмотрим более интересный случай\.

```cpp
float *Array = (float *)malloc(1000 * sizeof(float));
float *p = Array + 500;
unsigned A = 3;
int B = -5;
p[A + B] = 1.0f;
```

Код будет работать в 32\-битной программе и приведёт к падению 64\-битной программы\. Дело в том, что выражение "A \+ B" имеет тип unsigned int\. Оно будет равно 0xFFFFFFFEu\. Это конечно некорректно в любом случае\. Однако в 32\-битной системе при сложении указателя и числа произойдет переполнение\. В результате 32\-битная программа будет работать, не смотря на ошибку\.

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

```cpp
size_t Count = BigValue;
for (unsigned Index = 0; Index != Count; Index++)
{ ... }
```

Если в 64\-битной программе значение переменной Count станет больше UINT\_MAX, то возникнет вечный цикл\.

Все это только вершина айсберга\. Существуют 64\-битные ошибки связанные с использованием в коде магических чисел \(4, 32, 0xFFFFFFFF\)\. Есть ошибки в объявлении виртуальных функций\. И так далее\. Подробнее с различными паттернами 64\-битных ошибок можно познакомиться в статье "[Коллекция примеров 64\-битных ошибок](https://pvs-studio.ru/ru/blog/posts/cpp/a0065/)"\.

## Нюансы оптимизации 64\-битного кода

Помимо ошибок  неожиданную неприятность может доставить замедление скорости работы 64\-битной версии программы по сравнению с 32\-битной\. Вообще, 64\-битная программа должна работать быстрее \[[2](https://pvs-studio.ru/ru/blog/posts/k0003/)\]\. Однако на практике это не всегда так\.

Причины, по которым может произойти замедление:

* Используются неподходящие типы в качестве индексов массивов\. Это приводит к огромному количеству бессмысленных приведений типов\.
* Используются неподходящие типы для хранения данных\. Из\-за увеличения размера массивов объем потребляемой памяти может вырасти в 2 раза\. Как результат станет больше промахов в кэше и возрастет время пересылки данных по шине\.
* Увеличение размеров структур за счёт изменения выравнивания\. Это также влечёт увеличение количества используемой памяти\.

## Что же делать? Как же быть?

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

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

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

[Руководство по разработке 64\-битных приложений на языке Си/Си\+\+](https://pvs-studio.ru/ru/blog/lessons/)

Многим разработчикам, использующим Visual C\+\+, уже известны эти материалы\. Думаю, теперь они станут полезны и для тех, кто использует компилятор C\+\+Builder\. Раздел содержит информацию общего плана и будет полезен вне зависимости от используемых инструментов\.

## Viva64

Приведённой в [руководстве](https://pvs-studio.ru/ru/blog/lessons/) информации достаточно для написания корректных 64\-битных программ\. Но это мало поможет, если необходимо перенести на 64\-битную систему большой программный проект\. Перечитать весь код и выявить подозрительные места невозможно\.

Для решения этой задачи в статическом анализаторе PVS\-Studio существует набор диагностических правил под названием [Viva64](https://pvs-studio.ru/ru/pvs-studio/)\. Этот самый полный набор для выявления 64\-битных ошибок среди существующих\.

Теперь, когда анализатор PVS\-Studio стал доступен в среде C\+\+Builder, программисты смогут с меньшими потерями времени и сил произвести перенос кода\. Да, просмотреть все диагностические сообщения тяжело\. Но, во\-первых, это все равно лучше, чем долгое время вылавливать непонятные и плохо воспроизводимые ошибки \[[3](https://pvs-studio.ru/ru/blog/posts/cpp/a0043/)\]\. Во\-вторых, анализатор PVS\-Studio имеет развитую систему подавления ложных срабатываний и мы всегда готовы подсказать как её настроить\.

[Здесь](https://pvs-studio.ru/ru/pvs-studio/download/) вы можете скачать полнофункциональную демонстрационную версию PVS\-Studio\. На момент написания статьи анализатор умеет интегрироваться в Embarcadero RAD Studio XE2 и XE3 \(включая Update 1\)\. В дальнейшем, возможно, будут поддержаны и другие версии\.

## Подготовка к переносу кода

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

На всякий случай следует уточнить, что полноценный анализ возможен только в случае 64\-битного проекта\. Есть множество моментов, которые затрудняют выявление 64\-битных дефектов в 32\-битных проектах\. Самые наглядные пример это директивы препроцессора\. Если какое\-то участок кода не компилируется в 32\-битной программе, то соответственно он не будет проверен и ошибки в нём найдены не будут\.

## Заключение

Помимо приведённых в статье ссылок хочу порекомендовать ещё некоторые разделы нашего сайта:

* [Обзоры различных статей](https://pvs-studio.ru/ru/blog/posts/) по тематике разработки 64\-битных программ\.
* [База знаний](https://pvs-studio.ru/ru/blog/posts/) \(в основном связана с разработкой 64\-битных приложений\)\.
* [Twitter](https://twitter.com/Code_Analysis) с новостями о языке Си\+\+, разработке 64\-битных программ и так далее\.

Желаю вам безглючных 64\-битных программ\.

## Дополнительные материалы

1. Терминология\. [64\-битная ошибка](https://pvs-studio.ru/ru/blog/terms/0002/)\.
1. База знаний\. [Почему 64\-битные приложения работают быстрее 32\-битных?](https://pvs-studio.ru/ru/blog/posts/k0003/)
1. Андрей Карпов\. [64\-битный конь, который умеет считать](https://pvs-studio.ru/ru/blog/posts/cpp/a0043/)\.