Является ли C ++ подходящим для встроенных систем?

Общий вопрос, здесь и в другом месте. Является ли C ++ подходящим для встроенных систем?

Микроконтроллеры? RTOSes? Тостеры? Встроенные ПК?

Является ли ООП полезным для микроконтроллеров?

Сливает ли C ++ слишком много программиста на аппаратное обеспечение?

Должен ли Arduino C ++ (без управления динамической памятью, шаблонов, исключений) считаться «реальным C ++»?

(Надеюсь, эта вики послужит местом для сохранения этой потенциальной священной войны)

159 голосов | спросил 7 revs, 5 users 69%
Toby Jaffey
1 Jam1000000amThu, 01 Jan 1970 03:00:00 +030070 1970, 03:00:00

16 ответов


120

Да, C ++ по-прежнему полезен во встроенных системах. Как и все остальные, все равно зависит от самой системы, как 8-разрядный UC, вероятно, будет no-no в моей книге, хотя есть компилятор, и некоторые люди делают это (содрогаются). По-прежнему существует преимущество использования C ++, даже когда вы масштабируете его до чего-то вроде «C +» даже в 8-битном микромире. Что я подразумеваю под «C +»? Я имею в виду, что не используйте new /delete, избегайте исключений, избегайте виртуальных классов с наследованием, возможно избегайте наследования вместе, будьте очень осторожны с шаблонами, используйте встроенные функции вместо макросов и вместо этого используйте переменные const #defines.

Я работаю как на C, так и на C ++ во встроенных системах уже более десяти лет, и некоторые из моих юных энтузиазма для C ++ определенно износились из-за некоторых реальных проблем, которые потрясают наивность. Я видел худшее из C ++ во встроенных системах, которое я бы хотел назвать «программистами CS, дикими в мире EE». На самом деле, это то, над чем я работаю с моим клиентом, чтобы улучшить эту кодовую базу, которую они имеют среди других.

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

Я закончил два 4-часовых семинара по встроенному программному обеспечению на C ++ гуру C ++ Скотту Майерсу. Он указал на некоторые вещи о шаблонах, которые я никогда не рассматривал раньше, и насколько они могут помочь создать критически важный для безопасности код. Суть его в том, что у вас не может быть мертвого кода в программном обеспечении, которое должно отвечать строгим требованиям к критическому коду безопасности. Шаблоны могут помочь вам выполнить это, поскольку компилятор создает только код, необходимый для создания шаблонов. Тем не менее, нужно более основательно обучиться их использованию, чтобы правильно проектировать эту функцию, которую сложнее выполнить на C, потому что линкеры не всегда оптимизируют мертвый код. Он также продемонстрировал особенность шаблонов, которые могли быть достигнуты только на C ++, и, если бы Наблюдатель от Mars Climate Observer не смог сбой, NASA реализовала аналогичную систему для защиты единиц измерения в расчетах.

Скотт Мейерс - очень большой сторонник шаблонов и разумного использования вставки, и я должен сказать, что я все еще скептически отношусь к тому, чтобы быть gung ho о шаблонах. Я склонен уклоняться от них, хотя он говорит, что их следует применять только там, где они становятся лучшим инструментом. Он также подчеркивает, что C ++ дает вам инструменты для создания действительно хороших интерфейсов, которые просты в использовании и затрудняют неправильное использование. Опять же, это тяжелая часть. Вы должны достичь уровня мастерства на C ++, прежде чем сможете узнать, как применять эти функции наиболее эффективным способом, чтобы быть лучшим дизайнерским решением.

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

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

ответил GigaJoules 26 FebruaryEurope/MoscowbMon, 26 Feb 2018 14:12:26 +0300000000pmMon, 26 Feb 2018 14:12:26 +030018 2018, 14:12:26
52

C ++ абсолютно подходит для встроенных систем. Теперь я использую наличие /отсутствие хороших инструментов разработки (или их отсутствие) в качестве основного критерия для использования конкретного микропроцессора.

Области C ++, которые можно использовать во встроенных системах, потому что они имеют низкую стоимость ресурсов:

  • модульность, обеспечиваемая хорошим использованием классов /структур
  • templates , если , компилятор делает хорошую работу по их компиляции. Шаблоны - хороший инструмент для повторного использования алгоритмов для разных типов данных.

ОК:

  • виртуальные функции - я был против этого, но стоимость ресурсов очень мала (один vtable для class , а не для одного объекта, один указатель на vtable на объект, одна операция разыменования в вызов виртуальной функции), и большим преимуществом этого является то, что он позволяет иметь массив, содержащий несколько разных типов объектов, без необходимости знать, какой тип они есть. Я использовал это недавно, чтобы иметь массив объектов, каждый из которых представляет собой устройство I2C, каждое из которых имеет отдельные методы.

Области не использовать, главным образом из-за нехватки времени выполнения, которая неприемлема для небольших систем:

  • динамическое распределение памяти - другие упомянули об этом, но еще одна важная причина, по которой not использовать динамическое распределение памяти - это то, что она представляет собой неопределенность в сроках; многие причины использования встроенных систем предназначены для приложений реального времени.
  • RTTI (информация о времени выполнения) - стоимость памяти довольно большая
  • исключения - a definite no-no, из-за скорости выполнения hit
ответил GigaJoules 26 FebruaryEurope/MoscowbMon, 26 Feb 2018 14:12:26 +0300000000pmMon, 26 Feb 2018 14:12:26 +030018 2018, 14:12:26
34

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

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

a [i] = b [j] * c [k];

может генерировать около 4 страниц инструкций в зависимости от характера этих переменных.

Всякий раз, когда вы используете любой язык высокого уровня, и вы обеспокоены ограничениями времени и пространства, вам нужно знать, как функция each этого языка переводит в машинные инструкции на вашем MCU (по крайней мере, каждую используемую вами функцию). Это верно для C, C ++, Ada, что угодно. Вероятно, все языки будут содержать функции, которые не будут эффективно транслироваться на небольших MCU. Всегда проверяйте списки разборки, чтобы убедиться, что компилятор не генерирует команды инструкций для чего-то тривиального.

Является ли C подходящим для встроенных микроконтроллеров? Да, пока вы следите за сгенерированным кодом.
Является ли C ++ подходящим для встроенных микроконтроллеров? Да, пока вы следите за сгенерированным кодом.

Вот почему я думаю, что C ++ лучше C даже на 8-битных MCU: C ++ обеспечивает улучшенную поддержку для:

  • Скрытие данных
  • Более сильный ввод /проверка
  • Многоуровневая прозрачность с использованием классов
  • Шаблоны (как всегда, если они используются тщательно)
  • Списки инициализации
  • Const

Ни одна из этих функций не является более тяжелой, чем типичные функции C.

Когда вы перемещаете до 16 или 32-битных MCU, тогда становится разумным использовать более тяжелые функции C (стек, куча, указатели, массивы, printf и т. д.) Таким же образом, на более мощном MCU становится целесообразным использовать более тяжелые функции C ++ (стек, куча, ссылки, STL, new /delete).

Таким образом, не нужно содрогаться при мысли о C ++ на PIC16. Если вы правильно знаете свой язык и свой MCU, вы узнаете, как эффективно использовать их совместно.

ответил GigaJoules 26 FebruaryEurope/MoscowbMon, 26 Feb 2018 14:12:26 +0300000000pmMon, 26 Feb 2018 14:12:26 +030018 2018, 14:12:26
21

Я всегда нахожу эти дебаты интересными для чтения. Не столько для интеллектуального обсуждения плюсов и минусов различных доступных языков, но и потому, что вы обычно можете привязать чью-то позицию к этой теме, основываясь на своей работе /опыте /области интересов. Его право там с аргументами «преждевременной оптимизации» заключались в том, что майоры CS и программисты по техническому обслуживанию цитируют Кнута влево и вправо, а те, кто работает в реальном мире, где проблемы с производительностью, думают, что все они сумасшедшие (я являюсь членом более поздней группы чтобы быть справедливым).

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

Я часто слышу, как люди начинают эти аргументы: «Я эксперт в языке X и бла-бла». Я честно сразу же дискредитирую этих людей, потому что, на мой взгляд, они уже подошли к проблеме с неправильным углом и все после которые испорчены их желанием использовать свой инструмент для решения проблемы и показать, насколько она «крута».

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

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

По-моему, хорошие разработчики, будь то разработка программного обеспечения или аппаратного обеспечения, исследование проблемы, архитектор решения и поиск инструментов, которые позволяют им выражать решение «наилучшим образом». Не имеет значения, является ли требуемый инструмент тем, что вы никогда не использовали до этого, после того, как вы использовали 3-4 языка /средства разработки для проектов, которые собирают новый, должны иметь минимальное влияние на ваше время разработки.

Конечно, «лучший способ» - субъективный термин, а также должен быть определен на этапе исследования. Нужно учитывать множество проблем: производительность, легкость выражения, плотность кода и т. Д., Основанные на проблеме. Я не включил поддержку в этот список по какой-либо причине, мне все равно, какой язык вы выберете, если вы выбрали правильный инструмент и нашли время, чтобы понять проблему, это должно получиться «бесплатно». Трудно поддерживать код часто является результатом выбора неправильного инструмента или плохой структуры системы, это приводит к уродливому хакерскому беспорядку, чтобы заставить его работать.

Утверждение, что любой язык «лучше», чем любой другой, является глупым, не определяя особую проблему интереса. Объектно-ориентированный подход не всегда лучше функционального подхода. Есть некоторые проблемы, которые очень хорошо подходят для объектно-ориентированной дизайнерской парадигмы. Есть много таких, которых нет. Та же самая заявка может быть сделана о многих языковых функциях, которым, похоже, нравятся люди.

Если вы тратите более 20% своего времени на проблему, на самом деле набираете код, вероятно, создаете очень плохую систему или у вас очень плохие разработчики (или ваше обучение). Вы должны тратить большую часть своего времени на первую диаграмму проблемы и определять, как взаимодействуют различные части приложения. Придерживая группу талантливых разработчиков в комнате с маркерной доской и проблему, чтобы решить и сказать им, что им не разрешено писать какой-либо код или выбирать какие-либо инструменты, пока они не почувствуют себя комфортно со всей системой, они сделают больше для улучшения качества производительности и скорости, чем выбор любого нового горячего инструмента, гарантирующего улучшение времени разработки. (посмотрите вверх по разработке схватки как ссылку на полярность, противоположную моему аргументу)

Часто неудачная реальность заключается в том, что многие компании могут измерять ценность разработчика по количеству строк, написанных или видя «осязаемый результат». Они рассматривают 3 недели в комнате с маркерной доской в ​​качестве потери производительности. Разработчики часто вынуждены ускоряться через стадию «мысли» или вынуждены использовать инструмент, установленный какой-то политической проблемой внутри компании, «брат моего босса работает для IBM, поэтому мы можем использовать их инструменты», этот вид мусора , Или, что еще хуже, вы получаете постоянно изменяющийся набор требований от компании, потому что они не способны выполнять надлежащие исследования рынка или не понимают влияния изменений в цикле разработки.

Извините за то, что я немного отвлекся от этой напыщенной речи, у меня есть довольно сильные мнения по этому поводутема.

ответил GigaJoules 26 FebruaryEurope/MoscowbMon, 26 Feb 2018 14:12:26 +0300000000pmMon, 26 Feb 2018 14:12:26 +030018 2018, 14:12:26
15

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

Вопрос имеет большую актуальность при запросе системы (hard-) реального времени или с ограниченными ресурсами .

Для системы реального времени C ++ является одним из самых высоких языков, который по-прежнему подходит при программировании для строгих ограничений по времени. За исключением использования кучи (свободного оператора) у него нет конструкций с неопределенным временем выполнения, поэтому вы можете проверить, выполняет ли ваша программа свои требования к времени, и с некоторым опытом, который вы даже можете предсказать. Разумеется, следует избегать использования кучи, хотя новый оператор все еще может использоваться для одноразового распределения. Конструкции, которые C ++ предлагает по C, могут быть хорошо использованы во встроенной системе: OO, исключения, шаблоны.

Для очень ограниченных ресурсами систем (8-разрядные чипы, менее чем несколько Кбайт ОЗУ, отсутствие доступного стека) полный C ++ может оказаться плохой, хотя он может по-прежнему использоваться как «лучше C».

Я думаю, что это печально, что Ада, кажется, используется только в некоторых нишах. Во многих отношениях это Pascal ++, но без бремя быть совместимым с языком, который был уже серьезным беспорядком для начала. (редактирование: серьезный беспорядок, конечно, С. Паскаль - красивый, но несколько непрактичный язык.)

=============================================== =================

EDIT: я набрал ответ на новый вопрос («В каких случаях C ++ необходим, когда мы программируем микроконтроллеры»?), который был закрыт, ссылаясь на этот, поэтому я добавлю то, что я написал:

Никогда не существует всепоглощающей причины использования языка программирования any , но могут быть аргументы, которые имеют более или менее вес в конкретной ситуации. Обсуждения об этом можно найти во многих местах, причем занимаемые позиции варьируются от «никогда не использовать C ++ для микроконтроллера» для «всегда использовать C ++». Я больше с последней позицией. Я могу привести некоторые аргументы, но вам придется самому решить, сколько веса они переносят в конкретной ситуации (и в каком направлении).

  • Компиляторы C ++ встречаются реже, чем компиляторы C; для некоторых целей (например, 12 и 14 бит основных ПОС) вообще нет компиляторов C ++.
  • (хороший) Программисты на С ++ более редки, чем (хорошие) программисты C, особенно среди тех, кто также (несколько) хорошо осведомлен в электронике.
  • C ++ имеет больше конструкций, чем C, которые не подходят для небольших систем (например, исключения, RTTI, частое использование кучи).
  • C ++ имеет более богатый набор (стандартных) библиотек, чем C, но следствием предыдущего является то, что библиотеки C ++ часто используют функции, которые не подходят для небольших систем и, следовательно, не утихают на небольших системах.
  • C ++ имеет больше конструкций, чем C, которые позволяют вам стрелять в ногу.
  • C ++ имеет больше конструктов, чем C, которые позволяют предотвращать самостоятельно снимать себя в ноге (да, IMO это и предыдущий оба являются истинными).
  • C ++ имеет более богатый набор механизмов абстракции, поэтому он обеспечивает лучшие способы программирования, особенно для библиотек.
  • Функции языка C ++ (например, конструкторы /деструкторы, функции преобразования) затрудняют просмотр кода, чтобы увидеть сгенерированную машину и, следовательно, стоимость в пространстве и времени языковой конструкции.
  • Конструкция языка C ++ делает это менее необходимым, чтобы быть в курсе того, как именно они переведены на машинный код, потому что они делают «правильную вещь» более абстрактным образом.
  • Стандарт языка C ++ быстро развивается и быстро принимается большими компиляторами (gcc, clang, microsoft). C развивается довольно серо, и принятие некоторых новых функций (вариантных массивов) пугает и даже вернулось в более поздний стандарт. Этот момент особенно интересен тем, что разные люди используют его для поддержки противоположных позиций.
  • C ++, несомненно, является более острым инструментом, чем C. Можете ли вы доверять своим программистам (или вам самим) использовать такой инструмент, чтобы сделать красивую скульптуру, или вы боитесь, что они причинят себе боль и вы предпочтете остановиться на менее красивых, но более низких -режим продукта? (Я помню, что мой учитель-скульптор однажды сказал мне, что тупые инструменты могут в некоторых ситуациях быть более опасными, чем острые.)

В моем блоге есть несколько работ по использованию C ++ на небольших системах (= микроконтроллеры).

ответил GigaJoules 26 FebruaryEurope/MoscowbMon, 26 Feb 2018 14:12:26 +0300000000pmMon, 26 Feb 2018 14:12:26 +030018 2018, 14:12:26
14

По моему опыту, C ++ обычно плохо подходит для небольших встроенных систем. Под этим я подразумеваю микроконтроллеры и устройства без ОС.

Многие методы ООП С ++ полагаются на динамическое распределение памяти. Это часто отсутствует в небольших системах.

STL и Boost действительно демонстрируют мощь C ++, оба они огромны в области footprint.

C ++ побуждает программиста абстрагировать машину, где в ограниченных системах ее нужно охватить.

В прошлом году я поместил на мобильные телефоны коммерческий продукт для удаленного рабочего стола. Он был написан на C ++ и работал под управлением Windows, Linux и OSX. Но он в значительной степени полагался на STL, динамическую память и исключения C ++. Чтобы добиться успеха в средах WinCE, Symbian и без ОС, C-переписать был самый удобный вариант.

ответил GigaJoules 26 FebruaryEurope/MoscowbMon, 26 Feb 2018 14:12:26 +0300000000pmMon, 26 Feb 2018 14:12:26 +030018 2018, 14:12:26
9

Мой опыт: только после школьного обучения по старым программистам Bell Labs; работает в течение 3 лет, 2 - в рамках исследовательского проекта, сбор данных /управление процессом в VB.NET. Прошел 1,5 года, работая над приложением базы данных предприятия в VB6. В настоящее время работает над проектом для embedded ПК с 2 ГБ памяти, 512 МБ ОЗУ, 500 МГц x86 CPU; несколько приложений, работающих одновременно на C ++ с механизмом IPC между ними. Да, я молод.

Мое мнение: Я думаю, что C ++ может эффективно работать с учетом среды, которую я написал выше . По общему признанию, жесткая производительность в режиме реального времени не является обязательным требованием для приложения, в котором я работаю, и в некоторых встроенных приложениях это может быть проблемой. Но вот что я узнал:

  • C ++ принципиально отличается от C (т. е. нет C /C ++). Хотя все, что является допустимым, C является допустимым C ++, C ++ - это совсем другой язык, и вам нужно научиться программировать на C ++, а не C, чтобы эффективно использовать его в ситуации any . В C ++ вам нужно программировать объектно-ориентированное, а не процедурно, а не гибрид двух (большие классы с множеством функций). В общем, вам следует сосредоточиться на создании небольших классов с небольшими функциями и составить все небольшие классы вместе в более крупное решение. Один из моих коллег объяснил мне, что я обычно программировал на объектах, что является огромным беспорядком, и его трудно поддерживать. Когда я начал применять более объектно-ориентированные методы, я обнаружил, что поддерживаемость /удобочитаемость моего кода повысилась.

  • C ++ предоставляет дополнительные функции в форме объектно-ориентированной разработки, которая может обеспечить способ упрощения кода, чтобы упростить чтение /поддержку . Честно говоря, я не думаю, что есть много возможностей улучшить производительность /эффективность использования пространства при выполнении ООП. Но я думаю, что ООП - это метод, который может помочь разбить сложную проблему на множество маленьких кусочков. И это полезно для людей, работающих над кодом, элемента этого процесса, который не следует игнорировать.

  • Многие аргументы против C ++ связаны главным образом с распределением динамической памяти. C тоже имеет ту же проблему. Вы можете написать объектно-ориентированное приложение без использования динамической памяти, хотя одним из преимуществ использования объектов является то, что вы можете распределять эти вещи динамически простым способом. Как и в C, вы должны быть осторожны с тем, как управлять данными для уменьшения утечек памяти, но метод RAII делает это проще на C ++ (сделать динамическую память разрушаемой автоматически, инкапсулируя ее в объекты). В некоторых приложениях, где подсчитывается каждая ячейка памяти, это может быть слишком диким & wooly для управления.

EDIT:

  • WRT вопрос «Arduino C ++» : Я бы сказал, что C ++ без управления динамической памятью может быть полезным еще . Вы можете организовать свой код в объекты, а затем поместить эти объекты в разные места в вашем приложении, настроить интерфейсы обратного вызова и т. Д. Теперь, когда я развивался на C ++, я вижу много способов, которыми приложение со всеми данными, стек может быть полезен для объектов. Я признаю, что - я никогда не писал такое встроенное приложение для Arduino, поэтому у меня нет никаких доказательств моего заявления. У меня есть некоторые возможности для разработки Arduino в предстоящем проекте - надеюсь, я смогу проверить свои претензии там.
ответил GigaJoules 26 FebruaryEurope/MoscowbMon, 26 Feb 2018 14:12:26 +0300000000pmMon, 26 Feb 2018 14:12:26 +030018 2018, 14:12:26
9

Надеюсь добавить больше света, чем жара, к этой дискуссии о C ++ в системах с ограниченным доступом и с ограниченными ресурсами.

Проблемы в C ++:

  • Исключения, в частности, проблемы с ОЗУ, поскольку требуемый «аварийный буфер» (например, исключение из памяти) может быть больше, чем доступная оперативная память, и, безусловно, является отходом от микроконтроллеров. Для получения дополнительной информации см. n4049 и n4234 . Они должны быть отключены (что в настоящее время является неуказанным поведением, поэтому будьте уверены и никогда не бросайте). SG14 в настоящее время работает над лучшими способами этого.

  • RTTI, вероятно, никогда не стоит накладных расходов, его следует отключить

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

  • Распределение кучи. Хотя STL позволяет использовать пользовательские распределители, это может быть сложным для большинства программистов. Распределение кучи не является детерминированным (т. Е. Не жестким в режиме реального времени), а фрагментация может привести к непредвиденным ситуациям с памятью, несмотря на то, что они работали в тестировании. Сохранение книги, требуемое кучей для отслеживания свободного пространства и разного размера, может быть проблемой для небольших объектов. Обычно лучше использовать распределение пула (как на C, так и на C ++), но это может быть ненормальным для программистов на C ++, используемых только для использования кучи.

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

  • неявное взаимодействие с клише может быть проблематичным. Может показаться противоречивым, что проблемы с клипами относятся к категории C ++, но проблема возникает из-за неявного совместного использования ресурсов в параллельных средах (совместное использование более явным в C). Использование общей реализации newLib часто перетаскивается во множество раздутий, которые обычно не нужны в uCs, с другой стороны newLibNanno не является реентерабельным, поэтому доступ к нему должен быть сериализован (упрощает здесь). Это проблема и для C, но доступ более явный. Как правило, практически не следует использовать ничего из пространства имен std в контексте ISR, если вы не уверены, что он каким-либо образом не получает доступ к состоянию в clib (например, errory или куча). Его также важно, если вы используете потоки (я предпочитаю RTC), чтобы переопределять новые и удалять, чтобы синхронизировать доступ к malloc и бесплатно.

В заключение у C ++ есть некоторые проблемы, но они по существу все можно устранить или избежать.

Теперь для C здесь проблема более высокого порядка. У меня нет синтаксической способности в C для абстрактных вещей таким образом, что я могу выполнять оптимизацию или проверять инварианты во время компиляции. Поэтому я не могу правильно инкапсулировать вещи так, чтобы пользователю не нужно было знать, как они работают, чтобы использовать их, и большая часть моего обнаружения ошибок выполняется во время выполнения (что не только слишком поздно, но и увеличивает стоимость). По сути, единственный способ быть общим в C - через данные, я передаю строку формата printf или scanf, которая, например, оценивается во время выполнения. Тогда компилятору достаточно сложно доказать, что я не использую некоторые из возможных вариантов, которые теоретически возможны при передаче правильных данных, что означает создание потенциального мертвого кода и потерю потенциала оптимизации.

Я знаю, что я могу развязать shitstorm здесь, но мой опыт работы на 32-битных микроконтроллерах заключается в том, что в яблок яблоки сравнивают C и C ++, написанные экспертами (как в C ++ потенциально сильно templated). C ++ - гораздо более эффективный язык как только что-то должно быть вообще родовым (как в любой библиотеке), и они по существу эквивалентны в не общих случаях. Также новичок может использовать опыт эксперта по реализации библиотеки библиотеки на C ++.

В то же время на самом деле есть действительно несколько функций, к которым я не могу передавать неверные данные, как только вход не является int, а something, для которого я, по-видимому, использую int as метод представления, тогда есть потенциал, чтобы он ошибался (передайте недопустимое значение или «otherThing», а не «что-то»). В C мой единственный метод проверки, если пользователь получил это неправильно, находится во время выполнения. В C ++ у меня есть возможность выполнить некоторые проверки, а не все проверки, но некоторые проверки во время компиляции, которые являются бесплатными.

В концев день, когда команда C часто бывает такой же мощной, как и ее самый слабый программист, и в результате выигрыш в коде имеет либо мультиплеер из 1, либо штраф за производительность. Я имею в виду, что это либо высокая производительность для одного и только одного уникального задания в уникальной среде уникальных дизайнерских решений, либо он достаточно общий, чтобы использоваться в нескольких средах (другой микроконтроллер, другая стратегия управления памятью, другая латентность против. пропускная способность и т. д.), но имеет неотъемлемую стоимость исполнения.

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

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

ответил GigaJoules 26 FebruaryEurope/MoscowbMon, 26 Feb 2018 14:12:26 +0300000000pmMon, 26 Feb 2018 14:12:26 +030018 2018, 14:12:26
7

Да, проблема с C ++ - это увеличение объема кода.

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

Но, даже в C, для хорошо продуманной системы вам нужно держать все инкапсулированным. Хорошо спроектированные системы сложны, а C ++ дает программистам место для очень структурированного и контролируемого метода разработки. Существует стоимость изучения ООП, и если вы хотите переключиться на нее, вы ее очень согласитесь, и во многих случаях управление скорее продолжит работу с C, а не оплачивает расходы, так как трудно измерить результаты переключения, который повышает производительность. Вы можете найти статью гуру встроенных систем Jack Ganssle здесь .

Динамическое управление памятью - дьявол. На самом деле, черт не автомаршрут, динамическое управление памятью отлично работает на ПК, но вы можете ожидать перезагрузки ПК каждые несколько недель. Вы обнаружите, что по мере того как встроенная система продолжает работать в течение 5 лет, динамическое управление памятью может действительно запутаться и на самом деле начинают терпеть неудачу. Ganssle обсуждает такие вещи, как стек и куча в своей статье.

В C ++ есть некоторые вещи, которые более склонны вызывать проблемы и использовать много ресурсов, удаляя динамическое управление памятью, а шаблоны - это большие шаги, чтобы сохранить след C ++ ближе к размеру C. Это все еще C ++, вы делаете не требуется динамическое управление памятью или шаблоны для написания хорошего C ++. Я не понял, что они удалили исключения, я считаю исключения важной частью моего кода, которую я удаляю в релизе, но использую до этого момента. При полевом тестировании у меня могут быть исключения, генерирующие сообщения, чтобы сообщить мне об исключении.

ответил GigaJoules 26 FebruaryEurope/MoscowbMon, 26 Feb 2018 14:12:26 +0300000000pmMon, 26 Feb 2018 14:12:26 +030018 2018, 14:12:26
6

Я думал этот анти-C ++ rant Линус Торвальдс был интересен.

  

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

Он не говорит о мире встроенных систем, но ядро ​​Linux. Для меня актуальность исходит из этого: C ++ требует понимания более широкого контекста, и я могу научиться использовать набор шаблонов объектов, я не верю себе, чтобы помнить их, когда мне нужно обновить код через несколько месяцев.

(С другой стороны, я в настоящее время работаю над встроенным устройством, использующим Python (а не C ++, но используя ту же парадигму OOP), которая будет иметь именно эту проблему. В моей защите это встроенная система, достаточно мощная, чтобы быть называется ПК 10 лет назад.)

ответил GigaJoules 26 FebruaryEurope/MoscowbMon, 26 Feb 2018 14:12:26 +0300000000pmMon, 26 Feb 2018 14:12:26 +030018 2018, 14:12:26
6

Я думаю, что другие ответы сделали довольно хороший пример для плюсов и минусов и факторов принятия решений, поэтому я хотел бы просто обобщить и добавить несколько комментариев.

Для небольших микроконтроллеров (8 бит), никоим образом. Вы просто просите причинить себе боль, нет никакой выгоды, и вы потеряете слишком много ресурсов.

Для высококлассных микроконтроллеров (например, 32-разрядных, 10 или 100 МБ для оперативной памяти и хранилища), которые имеют достойную ОС, все в порядке, и я бы смел сказать, даже рекомендовал.

Итак, вопрос: где граница?

Я не знаю точно, но как только я разработал систему для 16-разрядного UC с 1 Мб ОЗУ и amp; 1 МБ на C ++, только чтобы потом пожалеть об этом. Да, это сработало, но лишняя работа у меня не стоила того. Я должен был приспособиться, чтобы такие вещи, как исключения, не приводили к утечкам (поддержка OS + RTL была довольно неудачной и ненадежной). Кроме того, приложение OO, как правило, делает множество небольших распределений, а накладные расходы кучи для них - еще один кошмар.

Учитывая этот опыт, я бы предположил, что для будущих проектов я выберу C ++ только в системах не менее 16 бит и не менее 16 МБ для RAM & место хранения. Это произвольный предел и, вероятно, будет меняться в зависимости от типа приложения, стилей кодирования и идиом и т. Д. Но, учитывая оговорки, я бы рекомендовал аналогичный подход.

ответил GigaJoules 26 FebruaryEurope/MoscowbMon, 26 Feb 2018 14:12:26 +0300000000pmMon, 26 Feb 2018 14:12:26 +030018 2018, 14:12:26
4

Есть некоторые особенности C ++, которые полезны во встроенных системах. Существуют и другие, такие как исключения, которые могут быть дорогими и чьи затраты не всегда могут быть очевидными.

Если бы у меня были мои барабанщики, был бы популярный язык, который бы сочетал лучшее из обоих миров и включал некоторые функции, которые отсутствуют на обоих языках; некоторые поставщики включают в себя несколько таких функций, но нет стандартов. Несколько вещей, которые я хотел бы увидеть:

  1. Обработка исключений немного похожа на Java, где функции, которые могут выдавать или исключать утечки, должны быть объявлены как таковые. Хотя требование для таких объявлений может быть несколько раздражающим с точки зрения программирования, это улучшит ясность кода в случаях, когда функция может возвращать произвольное целое число, если оно преуспевает, но может также потерпеть неудачу. Многие платформы могут обрабатывать это недорого в коде, например. с возвратным значением в регистре и индикацией успеха /отказа в флагом переноса.
  2. Перегрузка только статических и встроенных функций; я понимаю, что органы стандартов для C избегают перегрузки функций, чтобы избежать необходимости в изменении имени. Разрешение перегрузок статических и встроенных функций только позволило бы избежать этой проблемы и обеспечило бы 99,9% преимуществ перегрузки внешних функций (так как файлы .h могли определять встроенные перегрузки в терминах других названных внешних функций)
  3. Перегрузки для произвольных или специфических значений константных параметров, изменяемых во время компиляции. Некоторые функции могут быть очень эффективными при передаче с любым постоянным значением, но очень мало, если переданы переменные. В других случаях код, который может быть оптимизацией, если значение является постоянным, может быть пессимизацией, если это не так. Например:
    inline void copy_uint32s (uint32_t * dest, const uint32_t * src, __is_const int n)
    {
      if (n <= 0) return;
      else if (n == 1) {dest [0] = src [0];}
      else if (n == 2) {dest [0] = src [0]; dest [1] = src [1];}
      else if (n == 3) {dest [0] = src [0]; dest [1] = src [1]; dest [2] = src [2];}
      else if (n == 4) {dest [0] = src [0]; dest [1] = src [1]; dest [2] = src [2]; dest [3] = src [3];}
      else memcpy ((void *) dest, (const void *) src, n * sizeof (* src));
    }
    
    Если «n» можно оценить во время компиляции, вышеуказанный код будет более эффективным, чем вызов memcpy, но если «n» не может быть оценено во время компиляции, сгенерированный код будет намного больше и медленнее кода, который просто называется memcpy.

Я знаю, что отец C ++ не слишком увлекается встроенной версией C ++, но я думаю, что он может предложить некоторые значительные улучшения только при использовании C.

Кто-нибудь знает, если что-либо подобное выше рассматривается для любого типа стандарта?

ответил GigaJoules 26 FebruaryEurope/MoscowbMon, 26 Feb 2018 14:12:26 +0300000000pmMon, 26 Feb 2018 14:12:26 +030018 2018, 14:12:26
3

C ++ - это больше, чем один язык программирования:

a) Это «лучший» C б) Это объектно-ориентированный язык c) Это язык, который позволяет нам писать общие программы

Хотя все эти функции могут использоваться отдельно, лучшие результаты достигаются, когда три из них используются одновременно. Тем не менее, если вы решите выбрать только один из них, качество встроенного программного обеспечения увеличится.

a) Это «лучше» C

C ++ - сильный типизированный язык; чем C. Ваши программы выиграют от этой функции.

Некоторые люди боятся указателей. C ++ содержит ссылки. Перегруженные функции.

И стоит сказать: ни одна из этих функций не понесена в больших или медленных программах.

b) Это объектно-ориентированный язык

Кто-то сказал в этом сообщении, что абстрагирование машины в микроконтроллерах не является хорошей идеей. Неправильно! Все мы, встроенные инженеры, всегда абстрагировали машину, как раз с другим sintax, чем с C ++. Проблема, которую я вижу в этом аргументе, заключается в том, что некоторые программисты не привыкли думать в объектах, поэтому они не видят преимуществ ООП.

Всякий раз, когда вы готовы использовать периферийное устройство микроконтроллера, вероятно, что периферийное устройство было абстрагировано для нас (от вас самих или от третьего лица) в виде драйвера устройства. Как я уже говорил, этот драйвер использует C sintax, как показывает следующий пример (взятый непосредственно из примера NXP LPC1114):

/* Настройка таймера для соответствия и прерывания на TICKRATE_HZ * /

Chip_TIMER_Reset (LPC_TIMER32_0);

Chip_TIMER_MatchEnableInt (LPC_TIMER32_0, 1);

Chip_TIMER_SetMatch (LPC_TIMER32_0, 1, (timerFreq /TICKRATE_HZ2));

Chip_TIMER_ResetOnMatchEnable (LPC_TIMER32_0, 1);

Chip_TIMER_Enable (LPC_TIMER32_0);

Вы видите абстракцию? Таким образом, при использовании C ++ с той же целью абстракция выводится на следующий уровень через механизм абстракции и инкапсуляции C ++ при нулевой стоимости!

c) Это язык, который позволяет нам писать общие программы

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

Кроме того, статический полиморфизм достигается с помощью шаблонов.

Виртуальные методы, RTTI и исключения.

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

Наконец, совет о RTTI и исключениях: НЕ ИСПОЛЬЗУЙТЕ ИХ во встроенных системах. Избегайте их любой ценой!

ответил GigaJoules 26 FebruaryEurope/MoscowbMon, 26 Feb 2018 14:12:26 +0300000000pmMon, 26 Feb 2018 14:12:26 +030018 2018, 14:12:26
2

Мой фон, встроенный (mcu, pc, unix, другой), в реальном времени. Безопасность критическая. Я представил предыдущего работодателя в STL. Я больше этого не делаю.

Некоторое содержимое пламени

Является ли C ++ подходящим для встроенных систем?

Мех. C ++ - это боль, которую нужно написать, и боль для поддержания. C + - все в порядке (не используйте некоторые функции)

C ++ в микроконтроллерах? RTOSes? Тостеры? Встроенные ПК?

Снова я говорю Мех. C + не так уж плохо, но ADA менее болезненна (и это действительно что-то говорит). Если вам повезло, как я, вы можете сделать встроенную Java. Проверенный доступ к массиву и отсутствие арифметики указателей делают для очень надежного кода. Сборщики мусора во встроенной Java не имеют наивысшего приоритета, и есть область охвата памяти и повторного использования объектов, поэтому хорошо продуманный код может работать вечно без GC.

Является ли ООП полезным для микроконтроллеров?

Конечно. UART является объектом ..... DMAC - это объект ...

Машины состояния объекта очень просты.

Сливает ли C ++ слишком много программиста на аппаратное обеспечение?

Если это не PDP-11, C не является вашим процессором. C ++ изначально был препроцессором на C, поэтому Бьярне Страуструп переставал смеяться за медленные симуляционные симуляции, а AT & T. C ++ - это не ваш процессор.

Go получить MCU, который запускает java-байт-коды. Программа на Java. Смех у парней.

Должен ли Arduino C ++ (без управления динамической памятью, шаблонов, исключений) считаться «реальным C ++»?

Неа. как и все ублюдочные компиляторы C для MCU.

Forth, встроенная Java или встроенная ADA стандартизированы (ish); все остальное - печаль.

ответил GigaJoules 26 FebruaryEurope/MoscowbMon, 26 Feb 2018 14:12:26 +0300000000pmMon, 26 Feb 2018 14:12:26 +030018 2018, 14:12:26
-2

Встроенные системы предназначены для выполнения определенной задачи, а не для универсального компьютера для множества задач. Встроенная система представляет собой комбинацию компьютерного оборудования и программного обеспечения. C является матерью всех современных языков. Itâ € ™ s низкий уровень, но мощный полный язык и использует все виды аппаратного обеспечения. Таким образом, C /C ++ является оптимальным выбором для разработки программного обеспечения для встроенной системы, которое очень полезно для каждой встроенной системы. Поскольку мы знаем, что C является развивающимся языком. Операционная система UNIX написана на C. Поскольку успешная разработка программного обеспечения так часто связана с выбором лучшего языка для данного проекта, удивительно, что язык C /C ++ оказался подходящим как для 8-разрядных, так и для 64-разрядных процессоров ; в системах с байтами, килобайтами и мегабайтами памяти. C имеет преимущество независимости от процессора, что позволяет программистам сосредоточиться на алгоритмах и приложениях, а не на деталях конкретной архитектуры процессора. Однако многие из этих преимуществ одинаково применимы к другим языкам высокого уровня. Но C /C ++ преуспел там, где так много других языков в значительной степени не удалось?

ответил GigaJoules 26 FebruaryEurope/MoscowbMon, 26 Feb 2018 14:12:26 +0300000000pmMon, 26 Feb 2018 14:12:26 +030018 2018, 14:12:26
-4

& л; напыщенная >

Я думаю, что C ++ - это дерьмовый язык в первую очередь. Если вы хотите использовать ООП, напишите Java-программы. C ++ не делает ничего, чтобы обеспечить соблюдение парадигм ООП, поскольку прямой доступ к памяти полностью зависит от вашей возможности использования (ab).

Если у вас есть MCU, вы говорите, скорее всего, менее 100 КБ флэш-памяти. Вы хотите программировать на языке, абстракция которого есть: когда я объявляю переменную или массив, она получает память, период; malloc (иначе «новое» ключевое слово на C ++) должен быть более или менее запрещен к использованию во встроенном программном обеспечении, за исключением, возможно, в редких случаях одного вызова во время запуска программы.

Черт, во встроенном программировании есть (часто) раз, когда C недостаточно мал, и вам нужно делать такие вещи, как выделение переменных в регистры, и писать встроенную сборку, чтобы затянуть подпрограммы обслуживания прерываний (ISR) , Ключевые слова, такие как «неустойчивые», становятся важными для понимания. Вы тратите много времени на управление памятью на уровне бит , а не на уровне .

Почему вы хотите обманывать себя, думая, что вещи проще, чем они на самом деле?

& л; /& напыщенная GT;

ответил GigaJoules 26 FebruaryEurope/MoscowbMon, 26 Feb 2018 14:12:26 +0300000000pmMon, 26 Feb 2018 14:12:26 +030018 2018, 14:12:26

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132