Что бесит разработчиков в одном из самых популярных языков программирования

Александр Зайцев
Александр Зайцев

Разработчик, эксперт российской рабочей группы по стандартизации С++

Расскажите друзьям
Полина Константинова
Александр Зайцев, разработчик, эксперт российской рабочей группы по стандартизации С++, поделился своими мыслями по поводу одного из самых популярных языков программирования и объяснил, почему даже самые простые запросы пользователя могут стать для программиста ночным кошмаром.

О каком языке идет речь?

C++ – название, которое слышал едва ли не каждый человек, хоть немного интересующийся сферой IT. Это один из самых широко используемых языков программирования. На нем написано почти все, что нас окружает, начиная от значительной части ПО «Яндекса» и Google, заканчивая программным обеспечением для адронного коллайдера в CERN. Однако для программиста работа с C++ подобна игре на скрипке. Если ты виртуоз, то музыка твоя божественна, а вот если ты немного не дотягиваешь до требуемого уровня «Бог», то, скорее всего, пользователь неоднократно вспомнит тебя недобрым словом. В то время как, скажем, на Python даже новичок может создать что-то более-менее приличное и не вызывающее нервную чесотку у нетерпеливых пользователей.

C++ остро нуждается в трансформации, и этот факт никто не оспаривает. Работа по его непрерывному улучшению ведется последние 20 лет.

Однако это небыстрый процесс: чтобы создать взвешенный и удобный для всех вариант, каждое предложение проходит тернии утверждения в ISO – Международной организации по стандартизации. В этой работе участвуют и российские программисты: в 2014 году на базе «Яндекса» была создана российская рабочая группа, которая стала посредником между национальным сообществом разработчиков и ISO. Через нее любой заинтересованный человек может внести на рассмотрение свои предложения по изменению C++. Однако пока язык все еще далек от идеала. На простых примерах я покажу, как даже самые тривиальные запросы пользователя могут обратиться для программиста ночным кошмаром.


Покажи мне котика

Простой человек, заходя в браузер и нажимая на кнопку «покажи мне котика», не задумывается, о том, что пришлось пережить программисту, чтобы написать загрузку этого самого котика на сайт с сервера. Такой простой для пользователя процесс, как обращение к сайту и загрузка картинки, для программиста C++ оборачивается целой эпопеей.

Чтобы написать программу, которая будет взаимодействовать с сайтом в сети и загружать оттуда изображения, разработчику надо пройти семь кругов ада.

В стандартной библиотеке С++17 нет средств для работы с сетью, значит, программисту нужна библиотека стороннего автора. Стандартного способа подгрузить эту библиотеку нет – программисту надо потратить время на чтение документации, реализацию всех ценных указаний у себя на компьютере, вероятно, скачать себе дополнительные программы, запустить, например, Python для сборки проекта.

Для того чтобы с диска подгрузить картинку, также нужна сторонняя библиотека для работы с изображениями, потому что в стандартном наборе это не предусмотрено. И процедура повторяется с самого начала.


Какой породы котик?

После того как программа справляется с задачей показа котика, мы ставим ей еще одну: узнать породу этого котика. Пользователю предлагают нажать на соседнюю с «покажи котика» кнопку – «узнай породу». Предположим, что все породы записаны в файлы в формате JSON, а файлы лежат на сервере. JSON – один из наиболее популярных форматов файла с данными. Мы заранее максимально упрощаем задачу, делая предположение, что информация лежит именно в JSON.

Кажется, все очень просто: пойти на сервер, вытащить из файлов оттуда все породы, выбрать нужную нам и вернуть ее в ответ на запрос «узнай породу». На самом деле, нет.

В стандартной библиотеке C++ до недавно принятого стандарта  С++ 17 не было средств, чтобы узнать имена всех файлов, лежащих в определенной директории. В нашем случае – это имена файлов с породами котиков.

Но допустим, что мы работаем на C++17 и можем узнавать имена всех файлов директории беспрепятственно – нас ожидает более неприятная вещь: в пресловутой стандартной библиотеке C++ не предусмотрена работа с файлами json, хотя они распространены максимально широко и являются действительно очень удобными для работы с данными. На том же python программист просто и незамысловато просит «import json» и получает неограниченные возможности, а разработчика на С++ ожидают впереди очередные мытарства.


Игры, в которые играют люди

Любая игра, по сути, реализована на игровом движке – очень сложной и хитрой программе, громаде кода. Чем быстрее работает игровой движок, приятнее в нее играть, тем меньше системные требования у игры. Поэтому почти все самые популярные игры с хорошей графикой пишутся на C++, так как его производительность весьма высока.

Соотношение между скоростью работы программы и временем, затраченным на ее написание, для C++ более чем позитивное. То же самое, впрочем, нельзя сказать о его компиляции – то есть переводе исходного кода в машинный.

Компилироваться программа может от часа до суток и более – а процесс этот запускать надо всякий раз после внесения изменений в код для тестирования и выявления багов.

Происходит это потому, что в C++ нет модулей, а есть только заголовочные файлы. Заголовочные файлы дают возможность использовать один и тот же код в разных местах, экономя время программиста на написание, но каждый раз этот код компилируется заново, тратя нервы программиста на ожидание. Таким образом, система модулей сможет решить эту проблему.


Неопределенное поведение

Часто в школе учителя математики и прочих точных наук посмеиваются над литературой за ее волюнтаризм и неопределенность. Но на самом деле во взрослой жизни неопределенность поджидает нас на каждом шагу, особенно если речь идет о жизни программиста С++ или C. Бывают ситуации, когда программный код компилируется нормально, и кажется, что все хорошо. Но программа написана не вполне корректно и при некотором стечении обстоятельств можно натолкнуться на поведение, которое не определено стандартом языка C++.

Представим ситуацию: разработчик написал свою социальную сеть, где пользователи могут, скажем, ввести свой возраст и увидеть, во сколько раз они старше других людей. Все будет работать замечательно – до тех пор, пока кто-то не зарегистрирует в системе младенца, которому 0 лет.

При попытке найти отношение возраста пользователя к возрасту младенца мы получим деление на ноль. Заметить это проблему при разработке сложно, а компилятор вам ничем тут не поможет.

Современные компиляторы оптимизируют код исходя из соображения, что в нем нет неопределенного поведения. Так, например, если у вас в коде идет строчка a / b, то компилятор предполагает, что b не может быть 0 и может выкинуть проверку на 0, идущую после такого деления. Это сделает код быстрее и компактнее. Ситуаций неопределенного поведения масса, какие-то из них очевидны или отлавливаются специальными инструментами. На другие можно наткнуться, если делать в коде что-то нетипичное. Найти такую проблему может быть крайне трудно даже профессионалам своего дела с многолетним стажем. Новичков же подобное неопределенное поведение заставит отлаживать проект несколько недель и, скорее всего, введет в депрессию.

***

Это малая часть реальных примеров, на самом деле, перечислять их можно очень долго, углубляясь в дебри C++. Часть решений вероятно скоро войдут в новый стандарт, часть пока нет.

Шаг в три года – не такой большой, это время пролетает быстро. И, надеюсь, к 2023 году C++ станет еще удобнее, а картинки котиков в интернете будут радовать пользователей, не будучи головной болью программистов C++ .


Материалы по теме:

Актуальные материалы — в Telegram-канале @Rusbase

Нашли опечатку? Выделите текст и нажмите Ctrl + Enter


Комментарии

Зарегистрируйтесь, чтобы оставлять комментарии и получить доступ к Pipeline — социальной сети, соединяющей стартапы и инвесторов.
Big Data Conference
13 сентября 2018
Ещё события


Telegram канал @rusbase