C памяти и #defines - PullRequest
       23

C памяти и #defines

5 голосов
/ 28 августа 2009

Я работаю над встроенной системой, поэтому память очень важна для меня.

Одна проблема, которая повторяется, заключается в том, что мне не хватает места в памяти при попытке скомпилировать программу для него. Обычно это исправляется путем ограничения числа typedef и т. Д., Которые могут занимать много места.

Есть генератор макросов, который я использую для создания файла с большим количеством # define. Некоторые из них - простые значения, другие - граничные проверки

е

#define SIGNAL1 (float)0.03f
#define SIGNAL1_ISVALID(value) ((value >= 0.0f) && (value <= 10.0f))

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

Неиспользуемые # define занимают какое-то место в памяти?

Ответы [ 4 ]

20 голосов
/ 28 августа 2009

Нет, #defines не занимают места, если они не используются - #defines работают как find / replace; всякий раз, когда компилятор видит левую половину, он заменяет ее правой частью до того, как он фактически скомпилируется.

Итак, если у вас есть:

float f = SIGNAL1;

Компилятор буквально интерпретирует утверждение:

float f = (float)0.03f;

Он не будет никогда видеть СИГНАЛ1, он не будет отображаться в отладчике и т. Д.

4 голосов
/ 05 сентября 2009

Обычно это исправляется путем ограничения числа typedef и т. Д., Которые могут занимать много места.

Вы, кажется, несколько сбиты с толку, потому что typedef не занимают места во время выполнения. Они просто псевдонимы для типов данных. Теперь у вас могут быть экземпляры больших структур (typedef'd или иным образом), но это экземпляр, который занимает пространство, а не определение типа. Интересно, что «и т. Д.» Может охватывать это утверждение.

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

Вещи, которые занимают место:

  1. Исполняемый код (функции / функции-члены)
  2. Создание экземпляров данных (включая экземпляры объектов C ++)
  3. Объем пространства, выделенного стеку (или стекам в многопоточной системе).

То, что осталось, обычно доступно для динамического выделения памяти (ОЗУ), не используется или используется для энергонезависимой памяти (Flash / EPROM).

Сокращение использования памяти - это, прежде всего, случай выбора / проектирования эффективных структур данных, использования соответствующих типов данных, а также эффективного кода и разработки алгоритмов. Лучше всего ориентироваться на область, которая принесет наибольшую пользу. Чтобы увидеть размер объектов и кода в вашем приложении, получите компоновщик для создания файла карты. Это скажет вам, какие функции являются самыми большими, а также размеры глобальных и статических объектов.

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

Встроенная система не обязательно подразумевает небольшую память, поэтому вы должны указать. Я работал на системах с 64 МБ ОЗУ и 2 МБ Flash, и даже это скромно по сравнению со многими системами. Типичный микроконтроллер с ресурсами на кристалле, как правило, будет иметь гораздо меньше (особенно SRAM, который занимает большую площадь микросхемы). Кроме того, здесь важна архитектура Гарварда или фон Неймана, поскольку в архитектуре Гарварда данные и кодовые пространства разделены, поэтому нам нужно знать, чего вам не хватает. Если используется фон Нейман, использование кода / данных по-прежнему актуально, если код выполняется из ПЗУ или копируется из ПЗУ в ОЗУ во время выполнения (т. Е. Разные типы памяти, даже если они находятся в одном и том же адресном пространстве). .

Clifford

0 голосов
/ 28 августа 2009

unused #defines не занимает место в полученном исполняемом файле. Они занимают память в самом компиляторе при компиляции.

0 голосов
/ 28 августа 2009

Ну да и нет.

Нет, неиспользованные #defines не увеличат размер получаемого двоичного файла.

Да, все #defines (используемые или неиспользуемые) должны быть известны компилятору при сборке двоичного файла.

По вашему вопросу это немного неоднозначно, как вы используете компилятор, но почти кажется, что вы пытаетесь собрать непосредственно на встроенном устройстве; Вы пробовали кросс-компилятор? :)

...