Инструменты пользователя

Инструменты сайта



// C++17 Features

Пока лучший, что я нашёл, обзор новых фич C++17 с примерами и информацией о поддержке в компиляторах:

А вот обзор от команды Яндекса, которая теперь представляет РГ21 C++ Россия:

Вот и другие авторы начинают подтягиваться, в том числе - официальные источники:

// C++: алгоритмы с бинарным предикатом и значением

Или век живи - век учись.

Проблема описана здесь: https://stdcpp.ru/proposals/1386b162-0cde-49b7-a41e-90f2d9ee477c.

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

// CMakeProjectManager2: теперь и с Server Mode

Вот и прошло почти два месяца с последних изменений.

Время было потрачено:

  1. для ожидания некоторой стабилизации апстрима, так как, по сути, они требовали писать абсолютно новый код для реализации текущего функционала, а в условиях сильных и фатальных изменений, переписывать свой код на каждый чих… у меня столько времени нет.
  2. была предпринята неудачная попытка продвинуть код в апстрим.
  3. ну и изучался новый код, когда выпадало время, плюс раздумья - как применить функциональность и для серверного режима работы CMake.

Так как код отвергли, а это, по сути, написанная с нуля реализация старого функционала, то он был взят за основу новых изменений. Ну как основу - 99%.

Есть и изменения. Малой кровью была создана обёртка поверх Server Mode Reader'а, которая предоставляет всего его внутренние профиты за исключением классического вида дерева файлов.

Соответственно изменения, сделанные для старого ридера (Tealeaf Reader), который используется для версий CMake младше 3.7, в части отображения всех файлов, добавления, удаления и переименования теперь применимы и для Server Mode Reader.

Сразу же был найден и первый баг: неправильно обрабатываются дефайны из CMAke (add_definition()). Патч уже отослан, у себя в коде изменений делать не буду, подожду, пока попадёт в апстрим, потом засинхронизируюсь.

Функциональность же передачи Toolchain файлов выла дропнута. Можно делать настройки через Kit или же вручную создать параметр CMAKE_TOOLCHAIN_FILE и задать нужный. Главное не забудьте сделать Build → Clear CMake Configuration после этого. Ну и будьте готовы, что парсер C++ вас перестанет понимать, как минимум, частично.

Пакеты для Ubuntu 14.04 и 16.04 и производных уже доступны через PPA. Не забываем внимательно читать описание репозитория.

В ближайших планах подготовить ветку для стабильной версии QtC - 4.2. Там окажется только текущая функциональность и нового появляться не будет (если только кто-то не возьмёт её на сопровождение). Есть вероятность, что серверный режим будет выключен, так как он требует много смежных изменений и бекпортирования. Явные косяки тоже будут переноситься. В будущем, планирую саппортить только текущую версию QtC. Для старых не планирую даже исправления ошибок переносить. На всё это нужно время.

Если кто-то предложит варианты, как делать пребилды плагина для официальных версий QtC в автоматическом или полуавтоматическом режиме, буду рад выслушать.

Ну и с ошибками и предложениями: https://github.com/h4tr3d/cmakeprojectmanager2/issues

// CMakeProjectManager2 возвращается

В продолжение Qt Creator, CMake и судьба CMakeProjectManager2.

Ревью https://codereview.qt-project.org/#/c/180827/ расставило точки над i: "Project View == Build System View", билд система не может отображать все файлы проекта? Значит не будем показывать. Билд система не предоставляет возможности добавлять, переименовывать и удалять файлы в проекте? Значит не будем даже пытаться предоставить возможность это делать. Не удобно? Ничего, целостность концепции важнее.

Хотя… мне одному кажется, что абстракции тут текут? Ведь Project View сам по себе подразумевает именно проект?

Да, моё решение тоже не верх совершенства, даже так - костыль. Но он же реально помогает в условиях отсутствия более приличной альтернативы…

Ну и обоснование всего одно: «Я боюсь баг-репортов».

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

В любом случае, сейчас будет перезагрузка кода, потому как для новой кодовой базы, по сути, написан новый код. Сейчас буду думать, как наименьшей кровью в истории перенести новые изменения. Скорее всего придётся заревертить все прошлые мои изменений, привести master в состояние идентичное qtc-master, после чего просто сделать новый комит.

Ну а родной менеджер начнёт поддерживать данную функциональность, только кода CMake Server Mode сподобится на это. Удачи в ожидании :) Особенно при том условии, что конкуренты (KDevelop, Clion) это умеют делать.

// Qt Creator, CMake и судьба CMakeProjectManager2

Проект в стадии прекращения работы над ним…

// C++ и хорошие практики

Существуют хорошие практики программирования и их стоит изучать. Часть из них применима не всегда. Часть стандартов хорошо себя зарекомендовала, но стоят денег, например MISRA C++, но, помимо цены, ещё и достаточно консервативен и покрывает только язык до стандарта C++11 (выпущен в 2008 году).

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

  • The C++ Core Guidelines - естественно на первом месте, руководство от, можно сказать, создателей, корифеев языка. Основные составители Бьярне Страуструп, Герб Саттер и, конечно, сообщество. Развивается оперативно и быстро адаптируется под новые фишки стандарта.
  • High Integrity C++ Coding Standard - коротко и по делу. Немного пояснения: https://en.wikipedia.org/wiki/High_Integrity_C%2B%2B. Сейчас покрывает C++11. На этот стандарт даёт отсылки MISRA C++ 2008.
  • Все книги из Скотта Майерса из серии Эффективное программирование на C++.

Ну и на затравку: писать надёжный софт на C++ можно - C++ on Mars: Incorporating C++ into Mars Rover Flight Software ;-)

И стоит помнить, что есть практики, есть стандарты, но не стоит выключать свой мозг и обкладываться паттернами, бустом и прочими непотребствами, если вам нужно вывести всего лишь «Hello, world!».

// IncludeOS

Не мог обойти вниманием сиё творение.

Ребята запилили на суровом C++11/14 однозадачную сервисо-ориентированную операционку. Суть: операционка с минимальным футпринтом (образ 707кб), которая обслуживает ровно одну задачу (в их терминологии - сервис) и работает под управлением виртуальной машины: KVM, VirtualBox, используя возможности аппаратной виртуализации.

Сама операционка внутри представлена в виде асинхронного фреймворка, призванного, в первую очередь, строить сетевые приложения. Т.е. внутри реализован стек TCP/IP (судя по описанию, пока только IPv4, но IPv6 активно пилится). Многопоточность не поддерживается, реализован подход с кооперативной многозадачностью, которых очень хорошо ложится на асинхронную модель. Есть базовая поддержка файловых и дисковых операций (как минимум есть поддержка RAM-диска и файловых систем Ext4 и FAT).

При всём этом доступны для использования libc++ от LLVM (в том числе исключения), stdc в лице newlib.

В общем, интересное решение для сервис-ориентированных архитектур, для создания выделенных микросервисов. Плюс приятная лицензия: Apache2.

Ну и ссылки:

// Awesome C++

Вырвано из G+:

С сайта:

A curated list of awesome C/C++ frameworks, libraries, resources, and shiny things

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

Список раньше хостился на GitHub, теперь обрёл второе рождение в виде сервиса.

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

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

// std::string_view и временные объекты

Идея поста родилась при употреблении чая во внутрь на южной кухне.

Недавно смотрел один доклад (точнее бегло просматривал) про Rust и в момент, когда начался рассказ про life-time, глаз зацепился за такой опасный пример из мира C++:

string get_url()
{
  return "http://htrd.su";
}
 
string_view get_schema(string_view v)
{
  // тут какие-то действия, я их опущу
  auto result = v;
  return result;
}
 
int main()
{
  auto v = get_schema(get_url());
}

Что такое string_view - смотреть тут или тут. Если коротко - это невладеющая строка. Полезна для экономии на аллокациях, когда нужно работать с частями исходной строки.

В общем, из природы string_view следует и проблемы в коде выше: get_url() вернёт временный объект, который будет уничтожен в конце выражения, а следовательно, v будет ссылаться на невалидный участок памяти.

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

// C++ и 2D графика

Навеяно.

Из того, что мне понравилось:

    • Язык: C
    • Реализация: библиотека
    • Реально проста для простых применений. Куча примеров и статей в интернете. Поддерживает достаточно большое число платформ и компиляторов.
    • Язык: C++
    • Реализация: header-only
    • Библиотека отличается феноменальной простотой установки: только один заголовочный файл и всё. Минусом будет только тот факт, что нужно будет указать правильные флаги линковщика для целевой платформы. Но при этом весь базовый функционал для рисования и процессинга изображений присутствует. Дружится с OpenCV. Думаю, стоит рассматривать вариант этой библиотеки, когда нужно что-то по-быстрому нарисовать.
    • Язык: C++
    • Реализация: библиотека
    • С данной библиотекой особо не имел дел. Но примеры представляют её эдаким вариантом SDL, но на C++. Стоит попробовать.

Кроме того, на ресурсе cppreference.com есть свой список библиотек под различные задачи (в дополнение к предыдущему посту), и, в частности, для графики.

ЗЫ по ссылке выше есть интересная библиотечка для пользовательского интерфейса (GUI): nana, стоит пощупать. А так же для TUI: cwidget.

ЗЗЫ прочие ссылки:

// Коллекция ресурсов по современному C++

На RSDN промелькнуло, может ещё кому полезно будет:

Кто хочет дополнить - шлите мёрж-реквесты.

Прочие полезные ссылки, спасибо @sikmir:

// std::cout, std::cerr и std::clog

Сначала немного информации из мира С.

При запуске приложения (речь идёт о POSIX) вместе с ним открывается 3 файловых дескритоптора:

  • 0 - ассоциирован со стандартным вводом (stdin)
  • 1 - ассоциирован со стандартным выводом (stdout)
  • 2 - ассоциирован со стандартным выводом в поток ошибок (stderr)

В стандартной библиотеки Си используется FILE*-based буфферизируемый доступ к файлам и терминалу. В stdio.h объявлены следующие глобальные символы, которые отражают стандартные потоки ввода вывода:

  • stdin
  • stdout
  • stderr

Соответственно их свободно можно использовать вместе с семейством функций fread()/fprintf(), обеспечивая буфферизированный доступ.

Сами файловые дескрипторы POSIX объявляет через макросы в unistd.h:

  • STDIN_FILENO
  • STDOUT_FILENO
  • STDERR_FILENO

Соответственно их свободно можно использовать со всем семейством функций read(), write() и, даже, select()/epoll() и fcntl() (например, при помощи fcntl(O_NONBLOCK)+select+read можно реализовать аналог getch() из старого доброго Borland C++). Доступ через эти функции не буфферизирован.

Доступ к одному потоку разными механизмами в одной программе лучше не осуществлять: буферизация это уровень библиотеки C и внутреннего устройства FILE. write() или read() ближе к системным вызовам и ничего про это знать не обязаны. Как результат можете получить перемешивание текста даже в однопоточном приложении. Это не отменяет того файла, что сам fwrite() может, в конце концов, вызвать write().

На этом экскурс закончим и вернёмся в C++.

В C++ для работы с потоками служит библиотека iostream. Причём доступ к конкретному стриму может быть как буфферизируемым так и не буфферизируемым (зависит от потребностей).

Библиотека декларирует объекты, связанные со стандартными потоками:

  • std::cin - стандартный ввод
  • std::cout - стандартный вывод
  • std::cerr - стандартный вывод ошибок и
  • std::clog - для логирования

Про std::cin особо гооврить (пока?) не будем - он один, в своём роде. А вот про оставшиеся три стоит.

Итак, начнём с std::cout и std::cerr. В C++ они, помимо того, что связаны с разными дескрипторами, несколько отличаются поведением:

  • std::cout - буферизируемый
  • std::cerr - не буферизируемый

Такое отличие явственно следует из семантики использования: ошибку нужно увидеть сразу без ожидания каких-то дополнительных действий со стороны программиста типа std::flush или std::endl (он, кстати, делает и flush, поэтому, для большей производительности строки в нормальном выводе стоит заканчивать '\n', а не std::endl).

Ок, а что за std::clog? А это всего-лишь std::cerr + буферизация. И снова, семантика использования проста: диагностика может чуть и подождать, что бы не понижать производительность вывода, но смешиваться с нормальным выводом не есть хорошо, мы, ведь, можем использовать приложения в пайпе и, желательно, разделить диагностику и ошибки от обычного вывода.

Собственно, немного обобщая:

  • std::cout - используется для обычного вывода результатов работы программы на экран, эти данные могут быть переданы дальше по пайпу для обработки.
  • std::cerr - вывод сообщений об ошибке в обработке, что бы не подмешивались в основной поток и не ломали логику работы других программ в пайпе. При этом сообщение выводим максимально скоро.
  • std::clog - используем для разного рода диагностических сообщений, но когда использование std::cerr замедляет вывод из-за более частого дёргания системных вызовов, при этом, не подмешиваемся в основной поток и не мешаем работе других приложений в пайплайне.

Хорошим тоном, так же, является вывод справки по программе в std::cout, если вызвано с параметрами -h|–help - тогда её удобно смотреть в, например, less без дополнительных телодвижений, а вот справку по опциям, в случае неправильной установки какого-то параметра (или пропуска обязательного), лучше выводить (тут особой разницы не вижу) в std::cerr или std::clog.

И, на последок, лекция по поводу тормозов iostream и вообще, а как оно там внутри устроено:

// Source Specific Multicast и Asio

Недавно на ru.SO проскочил вопрос: как можно подключиться к SSM (Source Specific Multicast) группе?

Нюанс в том, что для этого используется опция `MCAST_JOIN_SOURCE_GROUP` для которой нет объекта-обёртки. Но, как оказалось, такой объект пишется самостоятельно на раз-два. Под катом я продублирую свой ответ, как пример подхода реализации нужного функционала. Пример не самый идеологически правильный, но, как оказалось, рабочий. Автор сам предложил свой вариант с захватом сырого хендла. Такой подход тоже имеет смысл в некоторых ситуациях2).

2) у меня случилось однажды так подружить сетевые абстракции Asio и libev, реализовав, тем самым, реактор на Asio :-)

// Обновление Qt Creator

Пока LOG, Habrahabr и другие гудят по поводу смены лицензионной политики в части Qt (переход на LPGL3) и QtC (переход с LGPL2.1 на GPL3 /именно GPL/ с исключением для плагинов), у меня дошли руки обновить PPA: https://launchpad.net/~adrozdoff/+archive/ubuntu/qtcreator-git

Ну и несколько интересных (для меня) изменений, которые стали доступны в этом билде. Добро пожаловать под кат.

// C++11: несуразность std::thread

Пост-вопрос.

Может кто объяснить, почему в стандарт вошла настолько обрезанная версия реализации std::thread? Ведь предлагаемый интерфейс не предоставляет абсолютно никаких средств передачи параметров потоку в момент создания, к примеру, тот же размер стека, что крайне актуально на всяких RTOS. При этом Boost.Thread такую возможность предоставляют средствами boost::thread::attributes:

    template <class F>
    explicit thread(attributes& attrs, F f);
 
    template <class F>
    thread(attributes& attrs, F &&f);
 
    template <class F, class ...Args>
    explicit thread(attributes& attrs, F&& f, Args&&... args);

Средства хоть и лимитированные, но доступ к native_handle атрибута позволяют тюнить параметры на конкретной платформе. Но в стандартной библиотеке нет и их. Нипанимать. Explain. Explain.

PS libstdc++ зато предоставляет достаточно простые средства, что бы добавить поддержку своих потоков (на той же RTOS), не прибегая к модификации кода библиотеки (если кому интересно, могу на пальцах разбросать как, но без полной реализации).