Обновить
200.91

C++ *

Типизированный язык программирования

Сначала показывать
Порог рейтинга
Уровень сложности

Отладка C++ программ в ОС GNU/Linux

Время на прочтение2 мин
Охват и читатели29K
Так уж случилось, что по долгу работы очень много времени провожу с операционными системами семейства GNU/Linux. Основным видом моей деятельности является разработка программного обеспечения на С++.

Так вот, основной проблемой при использовании отладчика – это отображение сложных контейнеров, например, stl-контейнеров.

Решение, которое я предлагаю, актуально для gdb. Этот отладчик поддерживает скрипты, написанные на языке python, а механизмы отображения сложных объектов, называются pretty printers. Т.е. чтобы отладчик отображал нам все правильно, необходимо указать ему где находятся скрипты с этими самыми pretty printers. Для указания отладчику дополнительных команд необходим файл .gdbinit.

Итак, попробую оформить все, как инструкцию, так и читать удобней, и сам не забуду.
Читать дальше →

У нас есть C++ 14!

Время на прочтение2 мин
Охват и читатели54K

C++ 14 готов!

По итогам заседания Исаква (Вашингтон, США) в феврале, мы запустили голосование за черновик международного стандарта (DIS) для следующего C++ стандарта. Это голосование завершилось в пятницу.

Сегодня мы получили уведомление, что голосование было единогласно успешным и следовательно мы можем приступить к публикации. Мы будем выполнять некоторые окончательные редакционные штрихи, для исправления некоторых орфографических опечаток и случайно пропущенных слов, а затем передадим этот документ в ISO для публикации в этом году как совершенно новый международный стандарт ISO/IEC 14882:2014(E) языка программирования С++, также известный как С++14.
Читать дальше →

Новая услуга: регулярный аудит Си/Си++ кода

Время на прочтение6 мин
Охват и читатели16K
PVS-Studio, аудит кода

До недавнего времени мы занимались исключительно развитием и продажей продукта PVS-Studio. Потом мы подумали и решили предлагать новую услугу: регулярный аудит кода. Про неё я и расскажу. Статья предназначена для менеджеров и тимлидов. Дабы не портить себе настроение и не минусовать, программистов прошу статью не читать.
Я руковожу программистами и готов читать дальше

Сериализация объектов Qt

Время на прочтение8 мин
Охват и читатели21K
Здесь меня будет интересовать как сериализовать объект Qt, передать его по сети и поддерживать между оригиналом и копией связь синхронизирующую состояние копии. Использовался Qt 4.8.
Читать дальше →

Статически типизированные продолжения

Время на прочтение12 мин
Охват и читатели11K
Намедни на RSDN был задан такой вопрос:
Пусть у нас есть функция, возвращающая полиморфный тип
class Base { virtual int foo() const = 0; };
class A : public Base { int foo() const { return 1; } };
class B : public Base { int foo() const { return 2; } };
class C : public Base { int foo() const { return 3; } };
class D : public Base { int foo() const { return 4; } };

Base* getconfig(char cfg) // не будем пока отвлекаться на уборку мусора
{
  switch(cfg)
  {
  case 'a': return new A();
  case 'b': return new B();
  case 'c': return new C();
  case 'd': return new D();
  default: throw std::invalid_argument("bad type");
  }
}

и функция, принимающая его экземпляры
int entry(Base* x, Base* y) { return x->foo()*10 + y->foo(); }

которую используют примерно так
void run(char cx, char cy) { std::cout << cx << cy << " : " << entry(getconfig(cx), getconfig(cy)) << std::endl; }


Можно ли протащить полиморфизм на стадию компиляции?
Читать дальше →

Реализация и тестирование Qt C++ клиента сетевого сервиса с асинхронным интерфейсом на примере Yandex Dictionary Api

Время на прочтение8 мин
Охват и читатели10K
Есть у меня один проект долгострой, в котором использую Yandex Dictionary Api. В процессе разработки решил поделиться опытом создания асинхронного интерфейса к интернет-сервису.

Если у вас есть интерес, как реализовать такой клиент с помощью Qt C++, то этот пост для вас.

Я не стал заострять внимания на тех моментах Qt, которые и так хорошо описаны. В статье я попытался раскрыть, как создавать асинхронные классы в Qt на базе конкретного примера.

Пример программы


Программа посылает на сервер Yandex Dictioanary Api запросы на перевод слов и затем, по мере поступления ответов от сервиса, выводит их на экран.

#include "Precompiled.h"
#include <QtYandexApi/QtYandexApi.h>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QtYandexDictionary yandexDictionary(QtYandexApi::getYandexKeyFromFile("dictKey"));
    QObject::connect(&yandexDictionary, &QtYandexDictionary::translated,
                     [](const QtYaWordTranslation& wordTranslation)
    {
        if (wordTranslation.isError())
            qDebug() << wordTranslation.errorString();
        else {
            QtYaWord wordForTranslation = wordTranslation.wordForTranslation();
            QtYaTranslatedWord translatedWord = wordTranslation.translatedWord();
            qDebug() << "\n***************";
            qDebug() << "Word: " << wordForTranslation.wordName();
            qDebug() << "Direction: " << wordForTranslation.fromLanguage() << "-" << wordForTranslation.toLanguage();
            qDebug() << "Main translation: " << translatedWord.mainTranslation();
            qDebug() << "Synonyms: " << translatedWord.synonyms();
            qDebug() << "Examples: ";
            for (const auto& example : translatedWord.examples()) {
                qDebug() << example.first << "-" << example.second;
            }
        }
    });

    QStringList russianWords, englishWords;
    russianWords << "дом" << "время" << "легенда" << "ключ" << "клавиатура" << "монитор" << "случай" << "один" << "два" << "три" << "четыре" << "пять" << "шесть";
    englishWords << "home" << "time" << "legend" << "key" << "keyboard" << "monitor" << "infection" << "one" << "two" << "three" << "four" << "five" << "success";

    for (const QString& word : russianWords) {
        yandexDictionary.translate(QtYaWord(word, "ru", "en"));
    }
    for (const QString& word : englishWords) {
        yandexDictionary.translate(QtYaWord(word, "en", "ru"));
    }

    return a.exec();
}


Читать дальше →

Можем ли мы доверять используемым библиотекам?

Время на прочтение9 мин
Охват и читатели24K
Can We Trust the Libraries We Use?
Сейчас любое крупное приложение состоит из множества сторонних библиотек. Хочется поднять такую тему, как доверие к этим библиотекам. В книгах и статьях можно встретить очень много рассуждений о качестве кода, методах тестирования, методологиях разработки и так далее. Но я не помню, чтобы кто-то рассуждал о качестве кирпичей, из которых строятся приложения. Давайте немного поговорим об этом. Например, есть Medicine Insight Segmentation and Registration Toolkit (ITK). Мне кажется, он написан весьма качественно. По крайней мере, я заметил в коде весьма мало ошибок. Но я не могу сказать, что код используемых библиотек столь же качественен. Тогда вопрос. Насколько мы можем доверять таким системам? Есть повод для размышлений.
Читать дальше →

Пополняем шпаргалки по C++: неявно-генерируемые перемещающий конструктор и оператор присваивания

Время на прочтение2 мин
Охват и читатели25K
Когда не так часто, как хотелось бы, приходится работать с языком, некоторые аспекты забываются. А некоторые никогда и не откладываются в голове. Поэтому, когда возникают вопросы, приходится отвлекаться и лезть в документацию.

Чтобы сэкономить время в последующем, а также, чтобы лучше понять в ходе обучения, крайне помогает вести конспекты и делать наглядные шпаргалки. Шпаргалку можно повесить рядом на стену. Хороши шпаргалки в виде блок-схем, по которым можно легко, по шагам, получить нужный результат (например выбрать правильный контейнер).

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

Читать дальше →

Проверка PVS-Studio с помощью Clang

Время на прочтение11 мин
Охват и читатели27K
Checking PVS-Studio with Clang
Да, да. Вы не ослышались. В этот раз статья «наоборот». Не мы проверяем какой-то проект, а проверили наш анализатор с помощью другого инструмента. На самом деле, подобное делали мы и раньше. Например, проверяли PVS-Studio с помощью Cppcheck, с помощью анализатора, встроенного в Visual Studio, смотрели на предупреждения Intel C++. Но раньше не было повода написать статью. Ничего интересного не находилось. А вот Clang смог заинтересовать своими диагностическими сообщениями.
Читать дальше →

Как я стенд для сборки с windows на wine мигрировал

Время на прочтение9 мин
Охват и читатели13K
image

Преамбула


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

И каждый раз, когда выходит новый Creative Suite, приходится портировать это дело. Что интересно, основные усилия уходят на то, чтобы собрать новую версию по новым правилам, и подогнуть инсталлятор. Потому как уж если дошел до стадии «оно компилируется», то как правило — работает. Хотя конечно есть нюансы — например в один прекрасный момент PlaceGun перестал раскладывать несколько выбранных изображений, только первое. Но об этом — в следующий раз.

И разумеется — хотелось бы это собирать под все версии и все платформы за раз, а не «открыл вижлу — собрал — закрып — повторил».

Итак, для сборки, нам нужны одновременно

  • MS VS 2005
  • MS VS 2005 sp1
  • MS VS 2008
  • MS VS 2010
  • MS VS 2012


Читать дальше →

Пишем простой интерпретатор на C++ с помощью TDD, часть 3

Время на прочтение19 мин
Охват и читатели14K
В первой части был написан лексер, а во второй части — парсер. Далее будет рассмотрена разработка вычислителя и фасада для всего интерпретатора, а также рефакторинг кода для устранения дублирования.

Вычислитель


Приступим к самому интересному. Вычисление выражения в постфиксной записи можно осуществить двумя способами: через рекурсию, неявно используя стек процесса, или используя явный стек. Реализуем второй вариант. Алгоритм с использованием явного стека такой:

  • Если на вход подан операнд, он помещается на вершину стека.
  • Если на вход подан знак операции, то соответствующая операция выполняется над требуемым количеством значений, извлечённых из стека, взятых в порядке добавления. Результат выполненной операции кладётся на вершину стека.
  • После полной обработки входного набора символов результат вычисления выражения лежит на вершине стека.

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

  • Если на входе пустой список, возвращаем 0.
  • Если на входе список с одним числом, возвращаем это число.
  • Если на входе [1 2 +], возвращаем 3.

Создадим новый тестовый класс и добавим первый тест.

TEST_CLASS(EvaluatorTests) {
public:
    TEST_METHOD(Should_return_zero_when_evaluate_empty_list) {
        double result = Evaluator::Evaluate({});
        Assert::AreEqual(0.0, result);
    }
};

Читать дальше →

Пишем простой интерпретатор на C++ с помощью TDD, часть 2

Время на прочтение16 мин
Охват и читатели14K
В первой части был написан лексер. Далее будет рассмотрена разработка парсера.

Парсер


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

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

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

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

Прикинем, какие тесты могут понадобиться для начала.

  • При получении пустого списка, возвращается пустой список.
  • При получении списка с одним числом, возвращается список с этим числом.
  • При получении [1 + 2], возвращается [1 2 +].
  • При получении [1 + 2 + 3], возвращается [1 2 + 3 +], так как оператор + является лево ассоциативным.
  • При получении [1 * 2 + 3], возвращается [1 2 * 3 +].
  • При получении [1 + 2 * 3], возвращается [1 2 3 * +], так как оператор * имеет больший приоритет.

Со скобками и ошибками разберёмся позднее. Итак, напишем первый тест из списка.

TEST_CLASS(ParserTests) {
public:
    TEST_METHOD(Should_return_empty_list_when_put_empty_list) {
        Tokens tokens = Parser::Parse({});
        Assert::IsTrue(tokens.empty());
    }
};

Читать дальше →

Создание аудиоплагинов, часть 16

Время на прочтение8 мин
Охват и читатели9.2K
Все посты серии:
Часть 1. Введение и настройка
Часть 2. Изучение кода
Часть 3. VST и AU
Часть 4. Цифровой дисторшн
Часть 5. Пресеты и GUI
Часть 6. Синтез сигналов
Часть 7. Получение MIDI сообщений
Часть 8. Виртуальная клавиатура
Часть 9. Огибающие
Часть 10. Доработка GUI
Часть 11. Фильтр
Часть 12. Низкочастотный осциллятор
Часть 13. Редизайн
Часть 14. Полифония 1
Часть 15. Полифония 2
Часть 16. Антиалиасинг



Чтобы наш SpaceBass звучал еще лучше, нужно создать осциллятор, в котором было бы меньше алиасинга. Это опциональное улучшение. Без него синтезатор будет работать как и раньше, но с ним звук на верхних октавах будет значительно лучше.
Читать дальше →

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

Пишем простой интерпретатор на C++ с помощью TDD, часть 1

Время на прочтение17 мин
Охват и читатели51K

Введение



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

Архитектура


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

Существует множество библиотек и инструментов, которые могут облегчить разработку интерпретаторов и компиляторов. Начиная от Boost.Spirit и заканчивая ANTLR и Bison. Можно даже запустить канал интерпретатора командной строки через popen и вычислить выражение через него. Целью данной статье является пошаговая разработка достаточно сложной системы с помощью TDD, поэтому будет использоваться только стандартная библиотека C++ и встроенный в IDE тестовый фреймворк.
Читать дальше →

Анимации на лямбдах в C++11

Время на прочтение3 мин
Охват и читатели20K


Компании-разработчики, как правило, не особо спешат переходить на новый Си++. Главным образом из-за поддержки его компиляторами, а точнее ее полного или частичного отсутствия. Недавно я решил узнать, что же есть новенького в плане поддержки C++11 компилятором GCC, и понял, что пора начинать. Благо, у нас в Ivideon лояльно относятся к новым технологиям и дают пробовать что-то новое.
Начал, конечно же, с самого вкусного — с лямбда-выражений! И с потоков.
Читать дальше →

Создание аудиоплагинов, часть 14

Время на прочтение11 мин
Охват и читатели6.2K
Все посты серии:
Часть 1. Введение и настройка
Часть 2. Изучение кода
Часть 3. VST и AU
Часть 4. Цифровой дисторшн
Часть 5. Пресеты и GUI
Часть 6. Синтез сигналов
Часть 7. Получение MIDI сообщений
Часть 8. Виртуальная клавиатура
Часть 9. Огибающие
Часть 10. Доработка GUI
Часть 11. Фильтр
Часть 12. Низкочастотный осциллятор
Часть 13. Редизайн
Часть 14. Полифония 1
Часть 15. Полифония 2
Часть 16. Антиалиасинг



Приступим к созданию полифонического синтезатора из тех компонентов, которые у нас имеются!

В прошлый раз мы работали над параметрами и пользовательским интерфейсом, сегодня мы начнем работу над лежащей в основе плагина полифонической обработкой аудио. В нашем случае мы сможем играть до 64-х нот одновременно. Это требует основательных изменений в структуре плагина, но мы сможем использовать уже написанные нами классы Oscillator, EnvelopeGenerator, MIDIReceiver и Filter.

В этом посте мы напишем класс Voice (голос), представляющий одну звучащую ноту. Затем создадим класс VoiceManager, следящий за тем, чтобы все ноты звучали и заглушались вовремя.
В следующем посте мы почистим код от ненужных устаревших частей, добавим модуляцию тона и приведем элементы управления интерфейса в рабочее состояние. На первый взгляд, работы полно. Но во-первых, у нас уже есть практически все нужные компоненты, а во-вторых, в конце у нас будет настоящий-полифонический-субстрактивный-блин-синтезатор!

Читать дальше →

Проверка Bitcoin

Время на прочтение4 мин
Охват и читатели31K
Bitcoin, PVS-Studio
Ничего эпического в этой статье не будет. Мы проверили с помощью PVS-Studio исходный код Bitcoin. Нашли всего пару подозрительных мест. Это не удивительно. Думаю, эти исходные коды не проверял только ленивый. Но раз проверили, то решил написать маленькую заметку. Так сказать, «для галочки».
Читать дальше →

Пишем на языке С/C++ в Windows под KolibriOS

Время на прочтение7 мин
Охват и читатели23K
image
KolibriOS – миниатюрная операционная система, ядро и большинство программ которой написано на языке ассемблер. Это, конечно же, не означает, что другим языкам программирования путь в KolibriOS закрыт. К примеру, за время эволюции этой операционной системы было несколько попыток разработать инструментарий или адаптировать библиотеки для создания приложений на языке C/C++. В репозитории KolibriOS до сих пор есть работающие примеры, использующие ранние наработки адаптации C/C++ кода, например (root)/programs/games/kosilka или (root)/programs/system/shell, использующие разные подходы и обертки C/Asm.

На текущее время самой перспективной из существующих библиотек, на мой взгляд, является newlib. Она состоит из адаптированной libc, C-оберкой над основными coreAPI функциями и toolchain’а для сборки.

К сожалению, в KolibriOS нативного компилятора C/C++ еще не существует, текущий toolchain предполагает сборку приложений в ОС Windows или Linux.

Данная статья является инструкцией по настройке newlib для ОС Windows.

Читать дальше →

Атрибут deprecated в С++14

Время на прочтение3 мин
Охват и читатели24K
Нормальным развитием любого кода является устаревание отдельных его частей (функций, классов и т.д.) и планомерное удаление их из проекта для снижения сложности и повышения безопасности кода. Просто убрать что-то обычно является плохой идеей — это может резко сломать какой-нибудь компонент, использующий удаляемую сущность. Хорошей практикой является пометка устаревшего кода каким-либо способом, который даст возможность использующим его программистам узнать о том, что он запланирован к удалению. (Прим. переводчика — Microsoft для этого изобрела свой велосипед, а ещё люди иногда пользовались #pragma message).

Новый стандарт С++14 вводит атрибут deprecated для пометки устаревших сущностей, планируемых к удалению в дальнейшем. Компилятор может выводить предупреждения при любой попытке их использования. Синтаксис принципиально новый для С++: атрибуты предполагается писать в виде списка через запятую, внутри двойных квадратных скобок. Вот так выглядит функция, помеченная как deprecated:

[[deprecated]]
void foo() {}

int main() {
	foo(); // в этом месте компилятор выведет предупреждение
}

Читать дальше →

Variadic Templates, Low Coupling и немного размышлений

Время на прочтение16 мин
Охват и читатели13K
Каждый программист, наверняка, сталкивался с ситуацией, когда в приложении имеется набор классов (возможно, сервисных), которые используются во многих участках программы. И вроде бы всё ничего, но как только появлялась необходимость менять эти классы, это могло негативно влиять и на вызывающий код. Да, как и указано в заголовке, речь в статье пойдет о том самом паттерне «Low Coupling».



Проблема не нова и давно известна. Путей ее решения может быть несколько, все зависит от предметной области. Я предлагаю читателю возможное решение, которое я нашел, занимаясь прикладной задачей. Как идеалиста, найденное решение меня устроило не полностью. Так же, оно было спроектировано в бОльшей степени от желания воспользоваться новыми возможностями стандарта C++11. Естественно, все написанное подлежит обсуждению, а возможно, кто-то предложит более стройный вариант.
Читать дальше

Вклад авторов