Перейти к содержанию
    

Статические переменные в функции.

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

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

Изменено пользователем jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 minutes ago, jenya7 said:

Есть какие то подводные камни?

Реентерабельность. Точнее, полное её отсутствие.

 

5 minutes ago, jenya7 said:

повышается читаемость функции - видишь какими переменными она оперирует

Не должна в большинстве случаев функция оперировать глобальными объектами.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, aaarrr said:

Реентерабельность. Точнее, полное её отсутствие.

 

Не должна в большинстве случаев функция оперировать глобальными объектами.

Реентерабельность? Что это значит?

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

12 минут назад, aaarrr сказал:

Не должна в большинстве случаев функция оперировать глобальными объектами.

Почему? Если мы берём класс то относительно класса все его функции работают как раз с глобальными объектами объявленными в классе. 
Если программа целиком имеет масштабы одного класса то почему бы описание класса и не опустить. Как раз будет набор глобальных переменных и функции для работы с ними. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

19 minutes ago, jenya7 said:

повышается переносимость функции из проекта в проект

На основании чего? И чем это будет отличаться от нестатических переменных?

19 minutes ago, jenya7 said:

повышается читаемость функции - видишь какими переменными она оперирует

То же самое без static.

19 minutes ago, jenya7 said:

Есть какие то подводные камни?

Статические переменные создаются раз и навсегда в ОЗУ. Место там резервируется под них во время процесса линковки. Соответственно эта переменная существует там всегда, пока есть питание. Прочитайте, что такое статические переменные, и где их следует действительно использовать. Один из вариантов - использовать их в обработчиках прерываний, когда нужно сохранить предыдущие результаты.

Пример:

sometype_t xTimerHandler() {
  static auto counter = 0;
  counter++; // при каждом вызове обработчика содержимое переменной counter будет увеличиваться на 1
  
  auto not_counter = 0;
  not_counter++; // а вот эта переменная КАЖДЫЙ РАЗ БУДЕТ ОБНУЛЯТЬСЯ при входе в обработчик, затем увеличиваться на 1
}

 

5 minutes ago, jenya7 said:

Реентерабельность? Что это значит?

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

5 minutes ago, jenya7 said:

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

Есть. Но статические переменные - это не глобальные переменные. Их область видимости (статических) ограничена ближайшей парой скобок {}.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, haker_fox said:

Статические переменные создаются раз и навсегда в ОЗУ. Место там резервируется под них во время процесса линковки. Соответственно эта переменная существует там всегда, пока есть питание. Прочитайте, что такое статические переменные, и где их следует действительно использовать. Один из вариантов - использовать их в обработчиках прерываний, когда нужно сохранить предыдущие результаты обработчика.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 minute ago, jenya7 said:

если я оперирую глобальной переменной

Глобальная переменная - это не статическая переменная. Глобальная переменная может быть статической. Вы же говорите о локальных статических переменных.

Вы точно понимаете различие между этими типами данных? Если да, то непонятен смысл вашего вопроса.

3 minutes ago, jenya7 said:

однопоточное приложение

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

4 minutes ago, jenya7 said:

часто бывает что я бегаю по коду ищу где эта переменная

Это решается аккуратным написанием кода и профессиональной IDE. Вы же используете конкретные типы данных в угоду читаемости. Это ошибочный путь.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, haker_fox said:

Вы же говорите о локальных статических переменных.

ну я имею ввиду что только эта функция использует переменную.

 

1 hour ago, haker_fox said:

Это решается аккуратным написанием кода и профессиональной IDE

IAR, VxWorks достаточно профессиональные, но у них периодически отсыхает индексация.

Изменено пользователем jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

39 минут назад, jenya7 сказал:

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

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

 

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

Да и вобщем - с увеличением кол-ва статических переменных (там где они не нужны) переносимость естественно ухудшается.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

 

39 minutes ago, jenya7 said:

Очень удобно - повышается переносимость функции из проекта в проект,

Вообще, из проекта в проект куда удобнее переносить модули.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

12 минут назад, haker_fox сказал:

Глобальная переменная - это не статическая переменная. Глобальная переменная может быть статической. Вы же говорите о локальных статических переменных.

Вы точно понимаете различие между этими типами данных? Если да, то непонятен смысл вашего вопроса.

Судя из вопроса - автор не понимает этого различия. И это после стольких тысяч вопросов на этом форуме. Да уж.... :russian_ru:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, jcxz said:

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

к примеру

uint8_t ResponseFromTube(uint8_t tube_id)
{
       static uint32_t no_ack_timeout;
       static uint32_t resp_timeout;
       static uint32_t bit_progress_timeout;
       static uint8_t st_count = 0;
       uint8_t result;
	   uint8_t task_done = 0;
  
       no_ack_timeout = globalSysTimer + (g_sfGcpcon[noAck] * 1000);
       resp_timeout = globalSysTimer + (g_sfGcpcon[rqpRto] * 1000);
  
       switch (tube_state)
       {      
            case ST_CAN_RX :
         
              if (globalSysTimer >= bit_progress_timeout)
			  {
				bit_progress_timeout = globalSysTimer + 1000;
				write_bit_process(st_count);
				st_count++;
				if (st_count > 5)
					st_count = 0;
			  }
                
                canbus_receive_one_channel(tube_id);
         
               if (globalSysTimer < no_ack_timeout)
               {
                  //и так далее
               }
         
            break;
      }    
}

при каждом вхождении в функцию мне нужны предыдущие значения

Изменено пользователем jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 минут назад, jenya7 сказал:

к примеру


uint8_t ResponseFromЕгиу(uint8_t tube_id)
{
       static uint32_t no_ack_timeout;
       static uint32_t resp_timeout;
       static uint32_t bit_progress_timeout;
       static uint8_t st_count = 0;
       uint8_t result;
	   uint8_t task_done = 0;
  
       no_ack_timeout = globalSysTimer + (g_sfGcpcon[noAck] * 1000);
       resp_timeout = globalSysTimer + (g_sfGcpcon[rqpRto] * 1000);
  ...
}

 

И...? Вам нужно срочно потратить лишнюю ОЗУ в программе и Вы не знаете как это сделать? Тогда да - это подойдёт. Если только оптимизатор не окажется умнее написавшего сиё и не удалит ненужные выделения памяти.

И больше не для чего.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

41 минуту назад, jenya7 сказал:

Есть какие то подводные камни?

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

Статическими в Сях имеет смысл делать локальные переменные-константы. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

9 minutes ago, jcxz said:

Если только оптимизатор не окажется умнее написавшего сиё и не удалит ненужные выделения памяти.

Увы, не удалит :mda:

Слово static - это как заклинание для компилятора и линкера. Ну, по крайней мере с теми  компиляторами, с которыми я работал 

 

 

имхо, если static и приписывать, то лучше к глобальным объектам (вынесенным из функции), дабы сделать их доступными только в пределах одного объектного файла. И то лишь временно. Потом все равно их нужно рассовывать по private полям классов.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...