Библиотека com_ports

com_ports — это небольшая статическая библиотека на языке С++, над которой я работал последние несколько месяцев. Она предназначена для работы с именами доступных в системе COM портов (RS-232).

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

Продолжить чтение →

Как правильно отменить net.Listener с помощью контекста?

net.Listener — это интерфейс в языке Go, который используется при реализации приёма подключения по протоколу TCP. Его метод Accept является блокирующим и не имеет входных параметров. Поэтому возникает вопрос: как правильно прервать ожидание подключения с помощью контекста?

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

Продолжить чтение →

Генерация строк по шаблону в Makefile

Сравнительно недавно при работе с Makefile я столкнулся с весьма интересной задачей. Над её решением пришлось поломать голову. И сегодня я хотел бы рассказать о самой задаче и о том, как её удалось решить.

Продолжить чтение →

Эволюция классов-врапперов

С врапперами (wrapper, обёртка) так или иначе сталкиваются все программисты. В этой статье под враппером я понимаю класс, который оборачивает экземпляр какого-то другого типа. Делаться это может по разным причинам (реализация другого интерфейса, RAII и др.).

Я бы хотел остановиться на том, как новые возможности языка C++ влияют на подходы к написанию врапперов. Мы посмотрим на такие «новые» возможности, как семантика перемещения, constexpr if, ref-qualifiers и deducing this.

Продолжить чтение →

Рассогласованный std::string

С классом std::string знакомы наверное все программисты C++. Но далеко не все знают, что он может находиться в рассогласованном состоянии. Под ним я понимаю такое состояние, при котором различные способы определения длины одной и той же строки (например, метод size и функция strlen) дают разный результат. Возникать оно может по разным причинам. Но, как правило, основная причина — NULL символ в неожиданном месте.

Сегодня я хотел бы обсудить именно такие «нездоровые» состояния std::string. Мы посмотрим, как они возникают, и попытаемся понять, почему они выглядят именно так.

Дополнительно мы обсудим один весьма спорный момент, связанный с методом std::string::reserve.

Продолжить чтение →

Исключения и конструкторы

Одним из лейтмотивов добавления исключений в язык С++ была необходимость уведомления об ошибках в конструкторах классов. Действительно, конструктор класса ничего не возвращает. Как ему сообщить о том, что он не может создать экземпляр класса? Для этого и используются исключения.

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

Продолжить чтение →

Взаимозависимые классы

При проектировании классов может возникнуть ситуация, при которой два класса одновременно ссылаются друг на друга. Например, у нас есть два класса A и B. И мы хотим иметь возможность создавать экземпляр класса A из экземпляра класса B. При этом нам нужна и противоположная возможность, создавать экземпляр класса B из экземпляра класса A.

Эту задачу нельзя решить в лоб, так как имеет место циклическая зависимость. Для её решения нужно использовать обходные пути. Сегодня я расскажу о двух таких путях: с помощью опережающего объявления (forward declaration) и с помощью шаблонов.

Продолжить чтение →

В чем я был неправ относительно std::condition_variable::wait?

std::condition_variable — это объект синхронизации, появившийся в C++11. Он используется, когда Ваш поток должен ожидать какого-либо сигнала от другого потока (например, о готовности данных для их последующей обработки).

Недавно мой коллега указал мне на то, что я неправильно понимаю работу с предикатом pred, который передается вторым параметром в метод std::condition_variable::wait. Он нужен для предотвращения ложного пробуждения потока (spurious wakeup). Интересный нюанс в том, когда он вызывается.

Продолжить чтение →

О блоке catch(…)

В С++ есть такая замечательная конструкция catch(...). С её помощью можно перехватить любое брошенное исключение, даже не зная его тип. Очень удобно. Но у такого подхода есть и серьёзный недостаток. Сегодня расскажу какой.

Продолжить чтение →