Подтвердить что ты не робот

С++ на микроконтроллерах с малым размером

Мне кажется, люди постоянно уклоняются от или, скорее, яростно выступают против использования С++ на микроконтроллерах, но я не могу для жизни понять, почему. Если вы держитесь подальше от больших библиотек С++ (например, STL), и вы не пытаетесь использовать сложные функции, такие как RTTI или обработку исключений, действительно ли есть какая-либо заметная разница между C vs С++? Имеет ли виртуальное наследование огромное влияние на сложность или след? Я бы подумал, что это будет немного дополнительной памятью, но большая часть сложности будет обработана компилятором, но опять же я не знаю много об этой темной магии. Я просто не понимаю, почему люди очень категоричны в использовании C, за исключением, возможно, для нескольких архитектур, для которых нет компиляторов С++ (если они есть). Похоже, что преимущества модуляции и шаблонов были бы без проблем, даже если вы не могли использовать свой cin или cout.

Я спрашиваю, потому что я занимаюсь некоторыми исследованиями для некоторых хобби проектов, над которыми я хотел бы работать. В идеале, я бы хотел работать с С++ строго для возможности хорошо модулизовать вещи, а также для подхода C "SomeClass_SomeMethod (struct object * this...)" к объектной ориентации. (Я бы предпочел объект Pascal для этих проектов, но, увы, поддержка этого языка не совсем звездная...) Я бы предпочел не переходить на более способный микропроцессор, потому что А. для проектов, которые я делаю, я не нужны тонны ресурсов.. Я не планирую писать 60 государственных фильтров Калмана или кодировать видео 1080p B. (настоящий кикер) Я бы хотел использовать процессоры, доступные в пакетах DIP и QFP. Мне нужна возможность прототипа без пайки или выпечки в моей тостерной печи.

Любые мысли?

4b9b3361

Ответ 1

В С++ вы, по сути, платите только за то, что используете больше и больше, чем в противном случае являетесь компилятором C, а некоторые из них бесплатны.

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

EETimes/Embedded.com за несколько лет провел ряд статей по этой теме:

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

Ответ 3

Конечно, это сильно меняется.

Я бы не использовал виртуальное наследование на "маленьком" MCU. Я даже не использовал бы кучу.

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

Но, по крайней мере, в моем кратком набеге на встроенный профессионал, подходящего компилятора С++ просто не было, а дрянной, который был доступен, стоил тысячи в год.

GCC является наиболее способным, широко доступным компилятором С++, доступным для встроенных платформ. Однако поддержка платформы очень неравномерна. Если у вас есть неограниченные ресурсы, EDG заявляет, что они принесут поддержку, превосходящую Comeau, на "вашу" встроенную платформу.

Ответ 4

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

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

Во-вторых, существует миф о том, что С++ объектно-ориентирован, а C нет. Объектная ориентация мозаичного слова сводится к трем вещам:

  • 1) Модульная конструкция с автономными объектами, которые не тесно связаны ни с чем другим. Это очень важный атрибут любой программы.
  • 2) Частное инкапсулирование данных и сокращение объема данных. Это довольно важный атрибут любой программы.
  • 3) Полиморфизм классов: классы, которые наследуют другие классы и ведут себя по-разному, когда унаследованы. Полиморфизм весьма полезен, но гораздо меньше - в небольших встроенных системах.

1) может быть полностью достигнута как в C, так и в С++, это вопрос программирования, а не синтаксиса языка. И это самый важный атрибут OO на сегодняшний день! К сожалению, в любом языковом стандарте нет ничего, говорящего о том, как разработать свою программу. В С++ ничего нет, что автоматически приведет к лучшей модульной конструкции, все это находится в руках программиста.

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

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

Ни один из языков не даст вам вещи, связанные с OO, красивыми и элегантными способами. Что С++ получает от немного менее неходового синтаксиса, он теряет, когда вы начинаете пробираться через undefined/неопределенное/определяемое реализацией поведение.

Казалось бы, весь аргумент OO не имеет большого значения, С++ не является большим улучшением, когда дело доходит до OO. Тогда что еще есть в С++, что мне понадобится в моей встроенной системе? Выделяется одна вещь: стандартизированный синтаксис ассемблера inline. Это, пожалуй, самое большое преимущество, которое С++ имеет над C, для встроенных систем.

Кроме того, экскременты, STL, шаблоны, RTTI, перегрузка overator, перегрузка функций и т.д. и т.д. - все более или менее бесполезные функции, без которых невозможно жить.

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

Ответ 5

Для "малой площади", где меня будет беспокоиться, это раздувание кода. Если ваш код должен находиться в небольшом фрагменте оборудования, экземпляр класса шаблона

 std::vector<int>

имеет свой собственный набор инструкций, отдельно от

 std::vector<double>

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

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

Ответ 6

есть ли какая-либо заметная разница между C vs С++?

По моему опыту существует большая разница в использовании ОЗУ.

Например: В настоящее время я работаю над С++ для ARM uC с 512 КБ FALSH и 64 КБ ОЗУ. Использование ОЗУ должно быть меньше 30 кБ, но в два раза больше, потому что каждая константа попадает в ОЗУ. Это потому, что почти невозможно (по крайней мере, с целями GCC и ARM) убедить компилятор оставить члены класса const во FLASH. Единственный способ добиться этого - использовать классы без конструкторов, объявить все публичные члены const и использовать списки инициализаторов агрегатов.

Чтобы все ухудшилось, С++ не позволяет именам членов в списке инициализаторов, как вы можете делать в обычном C:

struct St {  int b;  int a[3];  };

static const struct St st_array[2] =
{
    [1] = { .a = {1,2,3,},  .b = 10, }, // deliberately disordered to
    [0] = { .b = 8,  .a = { 4,5,6,}, }, // illustate the value of names.
};

Все C-компиляторы помещают эти константы в сегмент "постоянные данные" (во FLASH).

В С++ вам нужно будет сделать это:

class ClassA  // cannot have constructor or destructor
{
public:  // const data cannot be private for aggregate initialization
    const int b;
    const int a[3];
private:
    int priv_fn(int i);
public:
    int pub_fn();
};

static ClassA classA_array[2] = 
{   
    { 3, { 8, 9,10,}, },  // aggregate initialization 
    { 4, { 9,10,11,}, },  // better get the order right!!!
};

В зависимости от вашего компилятора даже это может не гарантировать, что константы остаются во FLASH.

И да, я знаю, с С++ 0x вы можете использовать списки инициализаторов с конструктором, и это то, что я делаю, но в тот момент, когда у вас есть конструктор, который вызывается во время выполнения, все инициализации становятся динамическими.

Технический отчет (спасибо MSalters) подтверждает следующее:

7.1.2 Конструкторы и ПЗУ В общем случае константные объекты классов с конструкторами должны быть динамически инициализированы. Однако в некоторых случаях инициализация времени компиляции может быть выполнена, если статический анализ...

Суть в том, что такой статический анализ не выполняется никаким компилятором, который у меня есть, и если мне нужно ограничить себя классами без конструкторов с public const и без именования инициализатора, тогда я мог бы также написать простой (и объект -ориентированный) C.