Какая разница (в терминах памяти), если я заранее объявляю аргументы в качестве переменных вместо записи их в строке вызова функции? - PullRequest
0 голосов
/ 10 июня 2018

Например, для фиктивной функции write(int length, const char* text){...}, есть ли разница в показателях памяти между этими двумя подходами?

write(18,"The cake is a lie.");

или

int len = 18;
char txt[19] = "The cake is a lie.";
write(len,txt)

Бонус: что если есть какое-то повторение?то есть цикл вызывает функцию несколько раз, используя массив, элементы которого являются предполагаемыми аргументами.

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

1 Ответ

0 голосов
/ 11 июня 2018

Это зависит от того, объявлено ли char txt[19] в области действия функции или в глобальной области (или пространстве имен).

Если в области действия функции, то txtбудет размещен в стеке и инициализирован во время выполнения из копии строкового литерала , находящегося в (только для чтения) сегменте данных.

Если в глобальной области видимости, то он будетвыделяется во время сборки в сегменте данных.

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

Пример 1:

int len = 18;
char txt[19] = "The cake is a lie.";
int main() {
    write(len,txt);
}

Здесь len (int) и txt (19 байт)+ выравнивание выравнивания) будет выделено в сегменте данных программы во время сборки.

Пример 2:

int main() {
    int len = 18;
    char txt[19] = "The cake is a lie.";
    write(len,txt);
}

Здесь будет размещен строковый литерал "The cake is a lie."в сегменте данных программы во время сборки.Кроме того, len и txt (19 байт + заполнение) могут быть выделены в стеке во время выполнения.Оптимизатор может опустить распределение len и, возможно, даже txt, но не рассчитывайте на это, так как это будет зависеть от многих факторов, таких как доступность тела write, что он делает в точности, качествооптимизатор и т. д. В случае сомнений посмотрите на сгенерированный код ( godbolt теперь поддерживает цели AVR).

Пример 3:

int main() {
    write(18,"The cake is a lie.");
}

Здесь строковый литерал "The cake is a lie." будет размещен в сегменте данных программы во время сборки.18 будет встроен в программный код.


Поскольку вы разрабатываете на AVR, стоит упомянуть некоторые дополнительные особенности, а именно, исполняемый файл приложения изначально хранится во Flash, и как только вы его «запустите», он будет скопирован в оперативную память.Можно избежать копирования в ОЗУ и сохранить данные во Flash с помощью ключевого слова PROGMEM (хотя для выполнения каких-либо значимых действий с данными вам потребуется скопировать их в ОЗУ).

...