Возврат значений из функции

Вопрос такой. Где-то читал тут , что при обьявлении функции, если в функции обьявлена переменная , она динамическая и при закрытии функции уничтожается , а место освобождается… И возможна ситуация когда RETURN вернул значение из этой переменной и уничтожил , а туда , куда значение должно было попасть , попасть не успело. Например прерывание и затерло освободившиеся место… Так вот насколько это реально и как правильнее в этой ситуации поступать .
Обьявлять эту переменную как глобальную или как локальную в функции но static?
По сути с точки зрения расхода памяти и оптимизации если место выделенное ей не может быть использовано (static) , то по сути что глобальная , что локальная static пофиг ( за пределами функции не используется ) . Или я что-то упускаю?
Спасибо.

Из прерывания переменные не возвращаются.

А если функция что-то возвращает, то static аккуратней и безопасней.

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

-del-

Я не говорил , что возвращаются переменные из прерывания , я сказал , что во время прерывания , ну или после него возможна ситуация когда свободное место чем-то забьется до возврата нужного мне значение в место откуда был вызов , ну например если в прерывании тоже переменная обявленна какая нибудь локальная будет…

Функция считывает некоторое кол-во ячеек из еепром внешней и возращает из функции кол-во ячеек которое удовлетворило условию.
соответственно

uint8_t eepMax

void Setup()
{
}

или

static uint8_t eepList(){
uint8_t tmpMax=0;

return tmpMax;
}

по сути и там и там байт занят следовательно пофиг , но может с других позиций непофиг …

Возвращаемое ЗНАЧЕНИЕ испортится не может. Но если возвращается указатель на переменную объявленную в функции, то возможна перезапись области на которое ссылается возвращаемое значение.

1 лайк

@romansochi , Вы уверены, что static в нужное место поставили? Пока что код иллюстрирует факт того, что вопрос, возможно, не отражает то, что реально хотите узнать.

Да, видимо Вы правы

uint8_t eepList(){
static  uint8_t tmpMax=0;

return tmpMax;
}

функция закончила работу , return возращает значение tmpMax в основную программу . Если я правильно понял то сперва байт tmpMax помечается как свободный и следующим шагом его значение должно прочитаться основной программой. Но если в этот момент возникнет прерывание и в обработчике этого прерывания потребуется выделить некоторое кол-во байтов то т.к байт уже помечен как свободный то он может переписаться…и основная программа получит мусор…
Или это касается только указателей,
И как все таки лучше возратить значение, чтобы точно быть в нем увереным

Все правильно! Значение предварительно закидывается на стек возврата или в регистры.

А так в принципе делать нельзя.

1 лайк

Не правильно, и статик тут никакой роли не играет.
По команде “return tmpMax;” значение tmpMax помещается в стек возврата или в регистры, откуда будет считано вызывающим функцию кодом.
В случае возникновения прерываний, используемые регистры сохраняются и восстанавливаются на выходе.

Нет, сначала значение tmpMax копируется в ячейку (или регистр), предназначенные для возвращаемого значения, и только потом происходит возврат в вызывающую программу и смещение указателя стека (т.е. в Вашей терминологии “байт tmpMax помечается как свободный”).

И еще: в Си/Си++ стек очищает вызывающая программа.

да и на ассемблере так жеж пишут

Простите, но Вы бредите. Если переменная ещё занята, то ничего не затрётся, а если уже свободна, значит она реально больше не нужна.

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

И ссылок тоже.

Просто. Не мудрствуя лукаво.

1 лайк

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

Совершенно верно , слышал звон но до конца не понял , поэтому и решил уточнить! тепреь вроде все понятно.