понедельник, 23 июля 2018 г.

[C++] Что такое warning C4291 и как с ним бороться

Самой яркой особенностью языка программирования C++ перед привычной мне Java является необходимость обеспечивать ручное управление памятью и на этом пути разработчика поджидает множество интересных особенностей. Например, если мы переопределяем оператор new, снабдив его нужными исключительно нам аргументами (так называемая class-specific placement allocation functions), то необходимо подобным же образом переопределить и оператор delete (имеется ввиду, что нужно определить оператор delete, имеющий сигнатуру void operator delete(void *ptr, user-defined-args...), иначе при возникновении исключительной ситуации в конструкторе класса будет не понятно какой оператор delete следует вызывать, чтобы освободить уже выделенную для создаваемого объекта данного класса память. Произойдет утечка памяти.

Предупреждение компилятора C4291


К счастью компилятор MSVC информирует разработчика об опасности, выбрасывая исключение C4291 no matching operator delete found; memory will not be freed if initialization throws an exception (код должен компилироваться с флагами компиляции /EHsc /W1). Например:

[1/2] Building CXX object src\memory\CMakeFiles\placement-new-delete.dir\PlacementNewDelete.cpp.obj
..\src\memory\PlacementNewDelete.cpp(67): warning C4291: 'void *MyClassA::operator new(size_t,MyAllocator &)': no matching operator delete found; memory will not be freed if initialization throws an exception
..\src\memory\PlacementNewDelete.cpp(32): note: see declaration of 'MyClassA::operator new'
[2/2] Linking CXX executable src\memory\placement-new-delete.exe

Подробно предупреждение компилятора C4291 описано в одноименной статье на MSDN.

Проблема заключается в том, что реализовать соответствующий оператор delete может быть не так то и просто. Как нетрудно заметить, оператор new в любом случае принимает аргумент size - размер требуемой памяти в байтах, оператор же delete такого параметра не принимает, а он может использоваться при выделении памяти и быть необходим, чтобы вернуть ее операционной системе.

Использование аллокатора для размещения объектов в памяти


Рассмотрим такой паттерн: использование для выделения памяти стороннего аллокатора, реализующего два метода: allocate и deallocate, каждый из которых принимает на вход параметр size_t size. Такой код довольно часто встречается в реализации JIT-компилятора в наборе компонентов для построения виртуальных машин Eclipse OMR, из чего я сделал вывод, что паттерн довольно распространен.

вторник, 17 июля 2018 г.

IBM открывает себя: WebSphere с открытым исходным кодом на JVM с открытым исходным кодом

Давно не писал заметки в блог, но есть новость и ей хочется поделиться: мой первый (и, я очень надеюсь - не последний), вклад в продукт с открытым исходным кодом Eclipse OpenJ9 был принят сообществом. Это - повод, а рассказать в данной заметке я хочу о проектах с открытым кодом, вышедших за последние годы из недр корпорации IBM. Возможно некоторые из них будут интересны вам лично или вашему бизнесу.

  • OpenLiberty - открытый сервер приложений Java EE, на базе него собирается WebSphere Liberty Profile. В качестве системы сборки используется Gradle (тесно интегрированная с bndtools, т.к. проект целиком и полностью основан на OSGi).

  • OpenJ9 - JVM с открытым исходным кодом, построенная на базе библиотеки классов из OpenJDK и другого проекта - OMR, содержащего кросс-платформенные компоненты для построения надежной и высокопроизводительной среды исполнения (т.е. на базе OMR можно построить не только JVM, но и среду исполнения для Python, Ruby или любого другого языка программирования). Какие это компоненты? Сборщик мусора, JIT-компилятор, библиотека общих кросс-платформенных функций, профайлер и т.д.

OpenJ9 и OMR открыты под эгидой сообщества Eclipse Foundation.

Теперь несколько слов о том, как собрать OpenJ9. Стоит сказать большое спасибо разработчикам за том, что они опубликовали довольно подробную инструкцию по сборке проекта с использованием вспомогательного Docker-образа и утилиты Make. Инструкция для JDK 8 может быть найдена по ссылке: Build_Instructions_V8.md, а для JDK 9 - Build_Istructions_V9.md. Обе инструкции подразумевают создание вспомогательного Docker-контейнера, содердащего компилятор C++, линковщик и все необходимые утилиты, библиотеки и заголовочные файлы. Т.е. можно не "захламлять" основное рабочее окружение если, например, разработка на C++ не является вашей основной деятельностью, а вам просто нужна свежая сборка JVM для тестов или экспериментов.