LittleBuster
@LittleBuster

С или modernC++ для IoT?

Использую OrangePi Zero для своих устройств с 256мб ОЗУ и АРМ 4-х ядерный

orangepi2-100691701-orig.jpg

Вопрос стоит так и никак иначе: Что лучше использовать для IoT чистый Си или С++ с shared_ptr, исключениями, Dependency injection, шаблонами, обёртками для каждой Си библиотеки, для которой нет аналогов С++ (типа работы с GPIO, LCD итд)?

Слишком ли я большой оверхед получаю с использованием С++ с его modern фишками и exception-ами и обёртками при получении итогового кода? По крайней мере время компиляции кода на плюсах для данных девайсов получается в разы дольше, чем для чистых Сей.

Огрызки С++ (типа отказа от использования исключений и shared_ptr) здесь меня не интересуют.
  • Вопрос задан
  • 626 просмотров
Решения вопроса 1
@Mace_UA
Не думаю, что оверхед от эксепшенов и shared_ptr'ов в C++ намного больше, чем оверхед от аналогичных вещей в Си. Ведь "эксепшены" там можно частично имитировать через setjmp/longjmp и прочие прелести, а "shared_ptr" навелосипедить ручками, сделав структуру для хранения данных, указателя на функцию-делитер и атомарных счётчиков strong и weak ссылок, работа с которыми будет осуществляться через соответствующие функции из <stdatomic.h>.
Ну и "weak_ptr" заодно заимплементить по аналогии с плюсовым, для полноты картины.

К чему я это всё?

Если Вам не нужен определённый функционал -- просто не используйте его.
И это утверждение справедливо вне зависимости от выбранного языка.
Если Вам не нужна некоторая часть языка -- это не причина отказываться от него полностью. Весь C++ на сто процентов, по-моему, не нужен вообще ни на одном проекте :)

А из фишек modern C++ в эмбеддеде наибольшую пользу, скорее всего, принесёт constexpr. В сочетании с шаблонами поможет вынести в компайл-тайм много всего -- причём, в отличие от рекурсивной функциональщины, использующей только шаблоны, это будет смотреться читабельно. В C++11 constexpr слабоват, но начиная с C++14 с ним есть где разогнаться.

Из структур данных в первую очередь посмотрите на array и tuple.

Для безопасности могут помочь enum class и nullptr.

Если в Вашем коде имеют место полиморфные иерархии, то override сделает код понятнее и предотвратит неприятные ошибки с hiding'ом вместо переопределения.

Рекомендую посмотреть на ютубе лекции Jason'а Turner'а -- у него были видосики о применении современного C++ в эмбеддеде. Он показывал сгенерированный ассемблер -- отличий от аналогичного низкоуровневого сишного кода вообще не было. Зато в исходном коде типобезопасность и расширяемость, которых добиться одной чистой Сишкой не всегда возможно.

Думаю, с выходом новых стандартов C++ и появлением их поддержки в компиляторах этот язык должен набрать большую популярность в эмбеддеде.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 3
TrueBers
@TrueBers
Гуглю за еду
Так говорите, как будто С++ это 2 вещи: shared_ptr и исключения :D

Вы смутно понимаете, похоже, в чём их назначение.

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

Два. Любые эксепшены, rtti, наследования, диспетчеризация и т. п. в embed'е это дикий оверхед. Но при этом, почему-то многие софтовые компании, включая гугл, просто выключают у себя в проектах поддержку исключений и rtti. И на этом "огрызке" всё работает почему-то. К тому же, размер бинарника для имбеда довольно важен и не на последнем месте. Выпилив исключения и rtti, можно очень хорошо выкинуть мусор.

shared_ptr — не серебряная пуля. Как уже сказал fshp, они используются в, ну просто, очень ограниченном количестве случаев. Их, как и исключения, нельзя пихать куда попало. Посмотрите выступления Шона Парента, почитайте его пейперы. Очень толковый мужик из Adobe, один из главных инженеров Фотошопа. Он там хорошо описывает и показывает на примерах, что shared_ptr — это просто хорошо замаскированная глобальная переменная, по сути, да ещё и с оверхедом от атомиков. И перед тем, как его использовать, сто раз подумайте, зачем он вам здесь нужен. В 99% случаев, можно обойтись без него, так же как и без RTTI. При этом, unique_ptr — очень удобная и полезная штука.

Вам современный C++ предлагает множество сишных способов возврата значения вместо эксепшенов. Вы можете возвращать тот же tied tuple, optional, variant, any, error_condition, error_code. Хоть они и сами любят повыбрасывать исключения, но код намного чище и легче отлаживать и понимать, чем миллион вложенных исключений с дикой иерархией и оверхедом.

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

Если вы из всего вышеперечисленного, пользуетесь только shared_ptr и исключениями, то C++ вам не нужен.
Ответ написан
Чего вы так вцепились в shared_ptr?
Если вы приглядитесь к своему коду, то с удивлением можете обнаружить, что в 50% случаях вы используете умные указатели вместо явного delete в деструкторе. Там, где можно и нужно инициализировать член класса на стеке, люди пихают указатель на него, а выделяют в куче.

Если посмотреть ещё глубже, то в оставшихся 49% мест в коде, где вы используете shared_ptr, на самом деле требуется ссылка на константу.

Ну и 1% реальной необходимости - это мизерный оверхед.

И вы как-то бросаетесь из крайности в крайность. Почему Modern C не рассматриваете?
Ответ написан
@marataziat
Джангист-тракторист
Golang :3
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы