Как стать автором
Поиск
Написать публикацию
Обновить

Думай о секундах свысока — как бы говорит нам Modern C++

Уровень сложностиПростой
Время на прочтение4 мин
Количество просмотров905

Зачем нам использовать Modern C++, особенно старших версий? Дурацкий вопрос, скажут сектанты, фанаты, фанатики, адепты. Оно же необходимо для большей выразительности, читабельности и ускорения всех возможных процессов, включая метаболизм; и еще для экономии времени. Что-то в этом есть, а кое-чего нет. Давайте рассмотрим пример из жизни.

Один программист (имя сохранено в редакции) писал себе спокойно код и написал примерно такое (для справки: используемый стандарт 2017):

#include <vector>

int main() {
    std::vector<int> vector;
    vector.push_back(0);
    vector.push_back(0);
    vector.push_back(0);
//здесь давайте на секунду представим себе, что содержимое вектора заранее неизвестно и он вполне может быть пустым
  int x=0;
    for(auto& n:vector){
      x++;
        //Сделай что-нибудь!
    }
    return 0;
}

Написал, сладко потянулся и отправил в билд.

К слову, билд штука непростая, состоит из многих этапов и занимает примерно час+.

Всего через 30 минут он обнаружил, что билд не удался. Дело в том, что у него на работе билд включает в себя прогон линтера. Линтер, жестокий и беспощадный, с ухмылкой сообщил, что обнаружил ошибку, мимо которой он не может пройти спокойно и просто обязан выполнить свой гражданский долг. 

Стали разбираться.

Ошибка оказалась следующей: линтер обнаружил, что при определенном стечении обстоятельств переменная х может оказаться неиспользованной. Ну то есть, когда вектор совсем пустой. Ахтунг!

Оказывается, в range-based for loop нельзя затащить локальную переменную, как в обычном цикле. Ну то есть можно, но об этом ниже.

Получив письмо счастья, автор сел разбираться.

И пришел к выводу, что есть несколько способов решить проблему:

1. приказать линтеру заткнуться и не вякать (хаха, смешно; то есть это осуществимо, но не принято).

2. после цикла эту несчастную переменную аннулировать, например выражением (void)x или что-нибудь в этом духе.

3. написать классический цикл, задать локальную переменную - как деды завещали.

4. перейти на старшую версию c++ (хахаха, гомерический хохот, долгие, несмолкающие аплодисменты)

5. или попытаться добавить локальную переменную в range-based for loop, как-то так:

for(int x=0; auto& n:vector)
{
  x++;
  //Сделай что-нибудь!
}

Тут правда есть небольшая засада: такой маневр допустим только  в версиях 2020 или 2023. И то, нет гарантии, что все, или хотя бы ведущие компиляторы его поддерживают. MSVC по крайней мере нет.

Лирическое отступление

Итого, что получается?

В язык затащили новую фичку. Но она оказалась малость недоделанной и всего спустя декаду ее таки доделали, но не все производители компиляторов об этом узнали.

И это уже не очень здорово, потому что если посмотреть, в какой степени компиляторы поддерживают разные версии стандарта, то можно загрустить:

ссылки:

https://en.cppreference.com/w/cpp/compiler_support/11.html

https://en.cppreference.com/w/cpp/compiler_support/14.html

https://en.cppreference.com/w/cpp/compiler_support/17.html

https://en.cppreference.com/w/cpp/compiler_support/20.html

https://en.cppreference.com/w/cpp/compiler_support/23.html

https://en.cppreference.com/w/cpp/compiler_support/26.html

Обратили внимание? Даже ведущие компиляторы, уже начиная со стандарта 2017 (а по факту даже с 2011) не гарантируют полную совместимость со стандартом как по самому языку, так и по стандартной библиотеке. И дальше расхождений все больше - в 2020 даже gcc, до этого бывший огурцом, начал уставать.

И даже друг с другом совместимость не гарантируют.
И с каждым новым стандартом все меньше производителей компиляторов собираются поддерживать эту муть.

Попросту говоря, если вы пишете код под стандарт 20хх под конкретный компилятор - не факт, что вы сможете скомпилировать его под другим компилятором! И это еще до того, как мы начала говорить о различиях в железе.


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

Например, стандарт 26 целиком не реализует вообще никто. Даже наполовину не. Даже стандарт 23 никто целиком не реализует.
А ведь планируется уже стандарт 29.
Тут уместно задать вопрос: а зачем вообще плодить стандарты которые реализуются через пень-колоду?
Но это наверно риторический вопрос, который невозможно расслышать через бой бубнов.

Казалось бы, что в этом плохого?
А то, что другие производители либо погибнут, либо уйдут в свои ниши.
В результате получится много совершенно непортабельного и неподдерживаемого кода.
Не то, чтобы раньше его не было - но раньше он происходил в основном из-за различий в железе.
Теперь к этому добавятся различия в стандартах и невежественные требования "сделать красиво", то есть модно, молодежно, читабельно и выразительно.
Но разве это остановит комитет? Нет, он будет продолжать кипучую деятельность, их бешеный принтер имеет большие творческие планы. A кучка упоротых фанбоев будет бегать вокруг с бубнами, выкрикивать дурацкие лозунги про прогресс и легаси и создавать 99% хайпа.

И это примерно то, что происходит.
Мне кажется, комитет совершенно потерял связь с целевой аудиторией, то есть с реальностью.

Почему-то вспомнилось название одной малоизвестной книги - "Пациенты рулят психбольницей."

Успехов всем нам.

Вернемся в исходную историю.

Как же наш герой справился с проблемой?

Во общем, эту проблему парень решил, неважно как (как-как: перешел на стандарт 2023! Хахаха, люди задыхаются от смеха и сползают с кресел!) Просто написал нормальный классический цикл.

Я бы хотел заострить внимание на другом.

Человек мог написать этот код по дедовским рецептам и все прокатило бы.

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

Затем минут 15 он выяснял где накосячил и как чинить.

Еще минут 30 он чинил - потому что мало починить, желательно еще локально скомпилировать и запустить, чтобы убедиться что все в порядке, а это занимает время.

И потом еще раз запустить билд.

Итого: за следование моде он заплатил более чем часом работы.

Finale

Выводы каждый пусть делает сам.

P.S. Этот текст был создан без использования БЯМ.

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Согласны с основным посылом статьи?
34.21%Да.13
42.11%Нет.16
5.26%Плевать.2
18.42%Я вообще не использую C++ и не собираюсь.7
Проголосовали 38 пользователей. Воздержались 6 пользователей.
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Вы довольны сложившейся ситуацией?
39.47%Да — новые стандарты необходимы, от них очень много пользы.15
15.79%Неуверен — все так сложно.6
10.53%Не очень — в принципе можно было остановиться на 2017 а дальше только модифицировать библиотеки.4
5.26%Нет — можно было остановиться на 2011 и продолжать возиться с библиотеками.2
28.95%Господи, я вообще не пользуюсь C++ и не собираюсь.11
Проголосовали 38 пользователей. Воздержались 4 пользователя.
Теги:
Хабы:
-3
Комментарии6

Публикации

Ближайшие события