# Глава 1.2. Всё, что вокруг
Свобода — один из столпов философии C++. Поэтому сам язык и его стандартная библиотека зафиксированы в стандарте языка, но все остальные инструменты разработчик выбирает сам. У C++ нет _стандартной_ системы автоматизации сборки, управления зависимостями, тестирования. Зато под каждую задачу найдётся несколько проверенных временем альтернатив.
## Экосистема
### Сборка
Чтобы собрать проект на C++, нужен компилятор. И вот четыре самых популярных: {#block-compilers}
- [GCC.](https://gcc.gnu.org/) По умолчанию установлен почти во всех десктоп-версиях дистрибутивов Linux. Разрабатывается в рамках [проекта GNU.](https://www.gnu.org/)
- [Clang.](https://clang.llvm.org/) Кроссплатформенный компилятор семейства Си-подобных языков под зонтиком проекта [LLVM.](https://www.llvm.org/)
- [Apple Clang.](https://opensource.apple.com/projects/llvm-clang/) Дистрибутив Clang для устройств Apple.
- [MSVC.](https://visualstudio.microsoft.com/vs/features/cplusplus/) Компилятор от Microsoft, отлично подходящий для компиляции проектов под Windows.
 {.illustration}
Вместе с дебаггером и сопутствующими инструментами эти компиляторы входят в состав тулчейнов сборки. О них мы поговорим в [главе про сборку проекта.](//courses/cpp/chapters/cpp_chapter_0111)
### IDE и редакторы
Выбор бесплатных кросс-платформенных сред для разработки на C++ довольно широкий. К сожалению, не все из них отличаются стабильностью и удобством. Есть две IDE, которые активно развиваются и позволяют комфортно работать с кодом:
- [Visual Studio Code.](https://code.visualstudio.com/docs/languages/cpp) Для разработки на C++ нужно поставить [расширение.](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools)
- [Qt Creator.](https://doc.qt.io/qtcreator/creator-how-to-install.html)
Также довольно популярна кроссплафторменная IDE CLion от JetBrains.
Многие пользователи приспосабливают для программирования на C++ свой любимый редактор: Sublime Text, Vim, Emacs, Atom. Для каждого из них найдутся плагины, упрощающие работу с кодом на C++.
Выбор пользователей macOS зачастую падает на [Xcode.](https://developer.apple.com/xcode/) А под Windows практически единственным вариантом для коммерческой разработки является [Microsoft Visual Studio.](https://visualstudio.microsoft.com/)
### Библиотеки и фреймворки
Стандартная библиотека C++ предоставляет контейнеры, алгоритмы, функции для работы с файловой системой, регулярными выражениями, датой/временем и многое другое. Тем не менее многого в ней не хватает. Например, C++ популярен для создания высоконагруженных сервисов. Но в стандартной библиотеке нет для этого _ни одного_ кирпичика! Веб-сервер, инструменты для работы с БД и очередями, веб-сокеты — все это привносится в проект через third party библиотеки. А некоторые компании предпочитают вести внутреннюю разработку всего этого добра. Вы удивлены?
Такое положение дел может показаться недосмотром со стороны комитета по стандартизации C++. Но вспомните о том, что C++ предназначен для _эффективного_ решения широкого круга задач. Если бы в станадртной библиотеке и был веб-сервер, им бы почти никто не пользовался! Потому что нельзя спроектировать веб-сервер, который будет производителен для всех сценариев работы. И пользователи языка все равно обратятся к кастомизированным сторонним решениям.
Так что если вы не отыщете в стандартной библиотеке средств для логирования, работы с сетевыми протоколами и форматами хранения данных, не удивляйтесь. Помните: на то есть причины.
Часть потребностей перекрывает коллекция библиотек [boost.](https://www.boost.org/) [Boost.Asio](https://www.boost.org/doc/libs/1_83_0/doc/html/boost_asio.html) предназначен для кросс-платформенной работы с сетью, [Boost.Beast](https://www.boost.org/doc/libs/1_76_0/libs/beast/doc/html/index.html) реализует взаимодействие по HTTP и через веб-сокеты. {#block-boost}
В коллекции boost есть библиотеки на многие случаи жизни. Однако зачастую более специализированные решения оказываются эффективнее и современнее, чем boost. Вот краткий список библиотек для решения типовых задач:
- Логирование: [spdlog.](https://github.com/gabime/spdlog)
- Тестирование: [GoogleTest,](https://github.com/google/googletest) [Catch2,](https://github.com/catchorg/Catch2) [doctest.](https://github.com/doctest/doctest)
- GUI: [Qt.](https://github.com/qt)
- Веб-сервер: [restinio,](https://github.com/Stiffstream/restinio) [Crow,](https://github.com/CrowCpp/Crow) [userver.](https://github.com/userver-framework/userver)
- Асинхронность: [libunifex.](https://github.com/facebookexperimental/libunifex)
### Линтеры, форматтеры и статические анализаторы кода
Ни один серьёзный проект на C++ не обходится без интеграции в CI/CD линтеров и статических анализаторов. Они не менее важны для выявления проблем, чем юнит-тесты. Вот два зарекомендовавших себя бесплатных инструмента:
- Линтер [Clang-Tidy.](https://clang.llvm.org/extra/clang-tidy/)
- Статический анализатор [Cppcheck.](https://cppcheck.sourceforge.io/)
В мире C++ отсутствует единое руководство по правилам именования и оформления. Некоторые проекты вырабатывают свои конвенции, а некоторые — используют распространённые, например [Google Code Style.](https://google.github.io/styleguide/cppguide.html) Для форматирования кода в соответствии с выбранным стилем к проекту подключают форматтеры, чаще всего — [clang-format.](https://clang.llvm.org/docs/ClangFormat.html)
## Мифы о C++
Как сказал автор C++ Бьерн Страуструп, есть два типа языков программирования: те, которые ругают, и те, которые не используют. C++ — один из популярнейших языков в мире, и конечно же вокруг него много критики. Часть критики вполне обоснована, но часть порождена мифами вокруг языка.
### Мифический язык C/C++
C++ появился на свет как надстройка над Си. Долгое время он продолжал быть надмножеством Си. Кроме того, при развитии C++ особый упор делается на обратную совместимость. Если копнуть ещё глубже, то по умолчанию все популярные компиляторы C++ собирают ваш проект таким образом, что к нему подключается стандартная библиотека Си.
Однако Си не стоял на месте. Он давно перестал быть просто подмножеством C++. На данный момент Си и C++ — это **два разных языка.** В них практикуются зачастую _противоречащие друг другу_ подходы к обработке ошибок, управлению ресурсами, построению абстракций, организации кода. Подходы, которые хороши или даже единственно возможны в мире Си, расходятся с принципами Modern C++.
Поэтому рекомендуем относиться к Си и C++ как к двум разным языкам, между которыми выстроено почти бесшовное взаимодействие. Оно реализовано через механизм, который называется интерфейсом внешних функций (FFI, Foreign Function Interface). FFI совмещает семантику и соглашения о вызове функций в Си и C++.
### C++ небезопасен
Не такой уж и миф, если честно. На C++ действительно легко допустить ошибки, открывающие бреши в безопасности проекта. Как правило это ошибки использования памяти после освобождения, обращения к неправильной области памяти, двойного освобождения.
Но риск этот сильно преувеличен, и на то есть причины:
- Многие не разделяют Си и C++. И если на C++ применять практики, принятые в Си, вы получите небезопасный код.
- В наши дни существует и здравствует огромное количество легаси на старом C++. В том числе это кодовые базы таких корпораций как Google, Microsoft, Apple. Эти проекты формировались во времена, когда в языке отсутствовали многие современные конструкции, а лучшие практики ещё не были выработаны. К сожалению, проблемы этих проектов зачастую проецируются на современный C++.
- Игнорирование современных возможностей языка. Термин «Modern C++» возник не просто так: начиная с C++11 в языке появилась масса средств для разработки безопасного, гибкого и читабельного кода.
Чтобы свести риск возникновения опасных ошибок к минимуму, используйте в связке:
- Modern C++.
- Тесты.
- Линтеры и статические анализаторы.
Иногда, несмотря на все старания, в проект все же проникают трудно локализуемые ошибки. Их поиску и исправлению способствуют инструменты для:
- Анализа памяти: [Valgrind](https://valgrind.org/) и [AddressSanitizer.](https://clang.llvm.org/docs/AddressSanitizer.html)
- Обнаружения состояния гонки (data races) между потоками: [ThreadSanitizer.](https://clang.llvm.org/docs/ThreadSanitizer.html)
- Поиска потенциально опасных конструкций: [UBSan.](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html)
## Области применения C++
Есть категории задач, для решения которых C++ подходит прекрасно. Но есть и те, для которых C++ плох.
C++ — удачный выбор для:
- Разработки производительного обобщённого кода. Например, высоконагруженных сервисов, SDK, библиотек для сложных вычислений, пайплайнов обработки данных.
- Низкоуровневых проектов: ОС, драйверов, микроконтроллеров, систем реального времени.
- Таких ниш как программирование на [GPU,](https://ru.wikipedia.org/wiki/Графический_процессор) графический рендеринг, gamedev, [HFT](https://en.wikipedia.org/wiki/High-frequency_trading).
А в этих случаях отдайте предпочтение языку попроще:
- Быстрое прототипирование. Скорость разработки — не самое сильное качество C++.
- Разработка продуктов, в которых _совершенно_ не важны производительность и экономия ресурсов. Использование в них C++ будет напоминать пальбу из пушки по воробьям.
Для всех остальных задач C++ будет если не идеальным, то по крайней мере хорошим выбором.
И наконец приведём краткий список знаменитых проектов на C++:
- [Chromium](https://github.com/chromium/chromium) — браузер.
- Базы данных [MongoDB](https://github.com/mongodb/mongo) и [ClickHouse.](https://github.com/ClickHouse/ClickHouse)
- [V8](https://github.com/v8/v8) — движок JavaScript от Google.
- [LibreOffice](https://www.libreoffice.org/about-us/source-code/) — офисный пакет.
- Игровые движки [Unreal Engine](https://www.unrealengine.com) и [Unity.](https://unity.com/)
- [Tensorflow](https://github.com/tensorflow/tensorflow) — библиотека для машинного обучения.
- [React Native](https://github.com/facebook/react-native) — фреймворк для разработки мобильных и настольных приложений на JavaScript и TypeScript.
- [LLVM](https://github.com/llvm/llvm-project) — инфраструктура для создания компиляторов. На базе LLVM построены компиляторы Rust, Swift, Kotlin, Julia и других популярных языков.
Вы запомнили, как выглядит Hello World на C++23? Самостоятельно воспроизведите его. {.task_text}
Вам помогут однострочные комментарии в коде. Они начинаются с двух слэшей: `//`. {.task_text}
Если возникнут сложности, воспользуйтесь подсказкой. {.task_text}
```cpp {.task_source #cpp_chapter_0012_task_0040}
// Импортируйте стандартную библиотеку.
// Определите функцию main — точку входа в программу:
// тип_возвращаемого_значения имя_функции()
// {
// тело функции
// }
// Внутри функции main вызовите функцию стандартной библиотеки
// для печати в консоль строки "Hello World".
// После импорта библиотеки и вызова функции не забудьте
// поставить символ-разделитель ";". Уже в следующей главе
// вы узнаете, для чего он нужен.
```
Модуль стандартной библиотеки называется `std`. Воспользуйтесь функцией `std::println()` из этого модуля. {.task_hint}
```cpp {.task_answer}
import std;
int main()
{
std::println("Hello World");
}
```
## Домашнее задание
1. Установите компилятор C++. Чем актуальнее версия — тем лучше.
2. Установите IDE или редактор кода, в котором вам будет комфортно работать.
3. Добейтесь компиляции и запуска Hello World в стиле C++17. Для компиляции Hello World в стиле C++23 потребуются дополнительные шаги, которые мы рассмотрим в следующих главах.
- Сохраните программу в файл `main.cpp`.
- Получите из исходного кода бинарный файл. Скомпилируйте файл из интерфейса IDE или из консоли.
- Запустите исполняемый файл. Если вы все сделали правильно, то увидите строку "Hello World".
----------
## Резюме
- В C++ нет стандартной общепринятой системы для автоматизации сборки, управления зависимости или форматирования кода. Зато для любой задачи можно подобрать опенсорсное решение под свои нужды.
- C++ хорош для написания производительного обобщённого кода и плохо подходит для быстрого прототипирования.
Наша группа в telegram. Здесь можно задавать вопросы и общаться.
Задонатить. Если вам нравится курс, вы можете поддержать развитие площадки!