пятница, 1 марта 2019 г.

[prog.thoughts] Еще раз на тему недовольства старых C++ников развитием языка

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

Для того, чтобы пояснить придется предаться воспоминаниям из глубокой старины :)

Когда-то давным давно, в начале 1990-х, когда я только-только начинал программировать на C++, ни я, ни мои однокурсники не заморачивались применением ключевого слова const. Да и примеры чужого C++ кода, который попадался мне в каких-либо статьях, примерах кода или библиотеках, так же не слишком изобиловали const-ами.

Поэтому при написании кода особо думать не приходилось. Передаешь указатель или ссылку куда-нибудь без const-а и все.

Но по мере приобретения опыта и расширения кругозора начало приходить понимание того, что const -- это нужная штука. Путь и редко, но защищающая тебя от ошибок. Ну а раз так, то пришлось учиться задумываться о том, где const нужен, а где нет. А так же привыкать к тому, что у объектов, которые могут использоваться как const-объекты, ряд методов должен быть помечен как const.

Не скажу, что это произошло быстро. Потребовалось несколько лет, но зато потом навык работы с const-ом был доведен до автоматизма.

Полагаю, что такой путь проходили многие С++ники, не обязательно такие старые, как я. Плюс к тому, для того, чтобы "освоить" C++ нужно привыкнуть и научиться делать выбор между кучей других возможностей. Например, где использовать наследование только в смысле композиции. Где нужно наследование с точки зрения полиморфизма. Где нужен полиморфизм, но где можно обойтись без run-time полиморфизма compile-time полиморфизмом на шаблонах. Где нужны перегрузки функций, где функции с дефолтными параметрами. Где шаблонные функции. Где специализации шаблонов.

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

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

Но потом приходит "современный C++", в котором есть constexpr, final, noexcept и возможности перегрузки методов для rvalue, и атрибуты, вроде [[nodiscard]].

И ты оказываешься как будто в самом начале пути. Тебе нужно заново учиться думать при написании кода. Может ли этот класс использоваться в constexpr контексте? Если да, то что у него должно быть помечено как constexpr? Должен ли этот класс помечаться как final? Эта функция, судя по всему, исключения не бросает, нужно ли помечать ее noexcept? Этот виртуальный метод должен использоваться в определенных контекстах, поэтому нужно ли его помечать как noexcept? Нужно ли делать перегрузку методов не только для const, но еще и для случая rvalue? Должна ли функция/структура/класс помечаться как [[nodiscard]]? Должен ли мой класс быть и Copyable и Moveable, или только Moveable, или только Copyable?

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

И вот осознание того, что твои многие годы опыта перестают что-либо стоить и что тебе нужно приобретать новые полезные привычки и менять свои взгляды на написание кода могут кого-нибудь очень сильно напрягать. Еще бы: какие-то люди взяли и выпихнули тебя из таким трудом завоеванной зоны комфорта. Кому такое понравится? ;)

4 комментария:

Анонимный комментирует...

IMHO, люди делятся на тех кому интересно узнавать новое и те, кому лень. Пока ты молодой и ничего совсем не знаешь, тебе приходится получать знания и навыки. А когда уже получен определенный "багаж", позволяющий нормально жить, то пути расходятся.

Если человек ленивый, он просто сидит на попе ровно и никуда особо не лезет или плавно переходит в руководители, где зарплата изначально выше, есть возможность "делегировать" рутину и возможности для попила тоже больше, потому что вся информация идет через тебя (не все руководители такие, но лениться и левачит на руководящей должности возможностей, обычно, больше). Однако, в программировании можно оставаться даже исполнителем и зарабатывать на комфортную жизнь.

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

EXL комментирует...

Согласен с предыдущим комментарием. Изучать что-то новое это всегда полезно, потому что этот опыт впоследствии может пригодиться в совершенно других областях, даже не связанных с изначальным объектом изучения.

P.S. Кажется я стал 1 000 000 посетителем в этом блоге, почитал пару постов и счётчик перевалил за 1 000 000 ^_^

eao197 комментирует...

@EXL: не 1000000 посетитель, к сожалению. Просто с вашей помощью число просмотров блога перевалило через этот показатель. Посетителей поменьше будет :)

Анонимный комментирует...

А у меня нет счетчиков, потому что mUblock (и как вообще люди смотрят интернет с рекламой, но к щастью, количество пользователей с блокировщиками постоянно растет).