реклама на сайте
подробности

 
 
> Язык С, ARM - простые вопросы
Slash
сообщение Jan 21 2009, 15:17
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 202
Регистрация: 10-04-05
Из: Санкт-Петербург
Пользователь №: 4 011



Здравствуйте!

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

А если программа строится в виде задач в бесконечном цикле:
Код
while (1)
{
    Task1();
    Task2();
    Task3();
}

Как обмениваться сообщениями между задачами? Мне понравилась система глобальных флагов - данные готовы к отправке, данные приняты, какое-то действие завершено и т.д.
Как без них?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
rezident
сообщение Jan 23 2009, 15:10
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(Demeny @ Jan 23 2009, 12:34) *
Теперь мне нужно прикрутить в проект второй UART с той же функциональностью, третий, четвёртый ... И вообще - я, как менеджер проекта, не знаю, сколько у заказчика будет UART-ов. Как мне Ваш модуль с минимальными доработками несколько раз включить в проект ?
Что-то я не понял затруднений. Статические переменные объявленные внутри функции имеют область видимости в пределах этой функции. Статические переменные объявленные вне какой-либо функции имеют область видимости в пределах данного модуля. Разве не так?
Могу конечно ошибаться, но по-моему singlskv имел в виду как раз такой случай. Глобальная переменная (объявленная вне тела функции) типа static имеет область видимости в пределах данного модуля. Никто не мешает дублировать эти модули в требуемых количествах. Хотя конечно же, если модуль состоит из одной функции, то разумнее было бы объявить эти переменные как static, но внутри самой функции.
Go to the top of the page
 
+Quote Post
singlskv
сообщение Jan 23 2009, 15:57
Сообщение #3


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(rezident @ Jan 23 2009, 18:10) *
Могу конечно ошибаться, но по-моему singlskv имел в виду как раз такой случай. Глобальная переменная (объявленная вне тела функции) типа static имеет область видимости в пределах данного модуля. Никто не мешает дублировать эти модули в требуемых количествах. Хотя конечно же, если модуль состоит из одной функции, то разумнее было бы объявить эти переменные как static, но внутри самой функции.
примерно это я и имел в виду,
только одна функция это частный случай и тогда действительно переменные нужно определять как статические внутри функции,
а вот если несколько функций в модуле работают с одной статической переменной, то без глобальных определений никак не обойтись,
но ведь можно ограничить область видимости таких переменных...

Я вот совсем теперь не понимаю за что ратует Demeny,
совсем без глобальных переменных ну никак.., и сохранение состояния автомата это один из примеров,
возможно речь о том что не нужно к ним обращаться напрямую ? то есть нужно предоставить интерфейс через вызов функций ?
ну дык это и не очень большой вопрос, и в каждом проекте он решаеться в частном порядке...
Go to the top of the page
 
+Quote Post
Demeny
сообщение Jan 26 2009, 09:58
Сообщение #4


Знающий
****

Группа: Свой
Сообщений: 648
Регистрация: 11-02-06
Из: Санкт-Петербург
Пользователь №: 14 237



Цитата(singlskv @ Jan 23 2009, 18:57) *
Я вот совсем теперь не понимаю за что ратует Demeny ...

Попробую ещё раз пояснить преимущества локальных переменных перед глобальными, пусть даже и статическими, т. е. видимыми в пределах одного программного модуля.
1) Если Ваш конечный автомат, или другой программный модуль (функция) хранит своё внутреннее состояние в статических или глобальных переменных, он тут же становится непригодным для многопоточного использования, проще говоря, становится "non-reenterable", во всяком случае, Вам придётся прибегнуть к специальным ухищрениям навроде синхронизации, чтобы использование Ваших функций в многопоточном приложении не вызвало крах всего приложения. Также она не может быть безопасно вызвана в качестве обработчика прерывания.
В случае локальных переменных всё безопасно - ведь у каждого потока свой стек, следовательно, каждый поток работает со своим уникальным набором переменных.
2) Ваш модуль в составе программы может вообще оказаться невостребованным (ну нет у клиента 8 UART-ов, заложенных по максимуму ...), однако память под буфера и прочие настройки Вы уже зарезервировали статически. Или же Ваш модуль нужен только на этапе инициализации - один раз при старте системы, а память занята уже "навсегда" ...
3) Доступ к локальным переменным осуществляется, как правило, быстрее, чем к глобальным (статическим), потому что любой оптимизирующий компилятор старается раскидать по возможности локальные переменные по регистрам процессора.
4) С точки зрения проектирования удобно представлять себе отдельную функцию, как законченный функциональный блок ("черный ящик") с входными и выходными параметрами. Это позволяет отлаживать функцию отдельно от остальных. Использование глобальных переменных размывает это понятие, поскольку, как ни крути, поведение функции зависит от поведения остальной части программы. Вот и будем ломать голову при отладке, какого же рожна глобальная переменная имеет "не то" значение, какое должно быть, и какая собака его испортила. Придётся бросить отладку текущей функции и заняться поиском "собаки". unsure.gif


--------------------
Сделано в Китае. Упаковано в России.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 26 2009, 10:32
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Demeny @ Jan 26 2009, 12:58) *
1) Если Ваш конечный автомат, или другой программный модуль (функция) хранит своё внутреннее состояние в статических или глобальных переменных, он тут же становится непригодным....


Либо с точностью до наоборот - ПРИГОДНЫМ. Конечный автомат получает указатель на структуру с котрой работать в данный момент и работает. Кроме того, опять, если нужны сколь нибудь реально-сложные автоматы в многопоточном приложении, то по любому он нужен и эти проблемы придется решать и отнюдь "просто используем локальные переменные".

Цитата
Вы уже зарезервировали статически.


Статически-то зачем? Спросили сколько надо у менеджера памяти. А вот стек, который потребуется Вам для Вашего непрогнозируемого количества "UART-ов" Вы как раз скорее всего статически-то и выделите. 

Цитата
3) Доступ к локальным переменным осуществляется, как правило, быстрее, чем к глобальным (статическим)


Из каждого "правила" есть исключения. Причем "как правило" они очень мешают жить. 

Цитата
.. поведение функции зависит от поведения остальной части программы.



Либо поведение этой функции ДОЛЖНО ЗАВИСЕТЬ от "остальной части" и тут Вас никакие ухищрения не заставят обойти эту зависимость. Либо НЕ зависят - в этом случае глубоко фиолетов глобальные или нет какие-то переменные, ибо в этом случае они по любому приватно находятся в пользовании одной функции.

 


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
A. Fig Lee
сообщение Jan 26 2009, 14:20
Сообщение #6


Знающий
****

Группа: Участник
Сообщений: 974
Регистрация: 4-04-08
Из: далека
Пользователь №: 36 467



Цитата(zltigo @ Jan 26 2009, 05:32) *
Статически-то зачем? Спросили сколько надо у менеджера памяти. А вот стек, который потребуется Вам для Вашего непрогнозируемого количества "UART-ов" Вы как раз скорее всего статически-то и выделите. 

 


Товарищи капиталисты, по-моему вы путаете теплое с мягким.

Глобальное - то, что видно отовсюду и всегда живет (возможно спорно),
Локальное - определено и живет в пределах обьекта к которому принадлежит.
Пример - переменные обьявленные внутри функции - локальные для етой функции (
совсем не обязательно они должны быть на стеке),
переменные обьявленные внутри класс/структуры - локальны для етих
классов/структур и глобально (без структуры/класса) - невидимы.
Могут размещатся в хипе, от етого глобальными не становятся.


--------------------
Верить нельзя никому, даже себе. Мне - можно.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jan 26 2009, 14:49
Сообщение #7


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(A. Fig Lee @ Jan 26 2009, 18:20) *
Товарищи капиталисты, по-моему вы путаете теплое с мягким.
Глобальное - то, что видно отовсюду и всегда живет (возможно спорно),

Статическое - это то, что видно только там, где надо, и всегда живет. Не путайте мертвое  с пьяным smile.gif
Go to the top of the page
 
+Quote Post
A. Fig Lee
сообщение Jan 26 2009, 17:55
Сообщение #8


Знающий
****

Группа: Участник
Сообщений: 974
Регистрация: 4-04-08
Из: далека
Пользователь №: 36 467



Цитата(_Pasha @ Jan 26 2009, 09:49) *
Статическое - это то, что видно только там, где надо, и всегда живет. Не путайте мертвое  с пьяным smile.gif



смотря о каких языках говорил - C или C++?

2. живет не всегда. например, обьявленная внутри функции - с момента обращения к функции.


Цитата(zltigo @ Jan 26 2009, 10:22) *
Это у Вас каша sad.gif из глобальности и области видимости, на что я уже сразу указывал.


видимость переменной может быть и глобальной, но она являтся локальной -
обьявить паблик мембер - член класса


--------------------
Верить нельзя никому, даже себе. Мне - можно.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jan 26 2009, 18:33
Сообщение #9


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(A. Fig Lee @ Jan 26 2009, 21:55) *
2. живет не всегда. например, обьявленная внутри функции - с момента обращения к функции.

Присмотритесь повнимательнее:  статические переменные живут изначально благодаря статической компиляции. И инициализация их (значением) производится в теле стартапа Поскольку это самое недорогое и здравое решение проблемы - позволить компилятору решить, где расположить переменную, оно применяется чаще всего.
Go to the top of the page
 
+Quote Post
sonycman
сообщение Jan 26 2009, 20:17
Сообщение #10


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Цитата(_Pasha @ Jan 26 2009, 22:33) *
статические переменные живут изначально благодаря статической компиляции. И инициализация их (значением) производится в теле стартапа

А если статическая переменная локальная? Разве её инициализация будет производиться в стартапе?
Go to the top of the page
 
+Quote Post
singlskv
сообщение Jan 26 2009, 20:27
Сообщение #11


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(sonycman @ Jan 26 2009, 23:17) *
А если статическая переменная локальная? Разве её инициализация будет производиться в стартапе?
Переменная из моего предыдущего поста статическая и объявлена в теле функции,
ее инициализация будет проведена в стартапе.



Более того(если захотеть), менять ее можно будет и из другой функции.
Go to the top of the page
 
+Quote Post
rezident
сообщение Jan 26 2009, 20:40
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(singlskv @ Jan 27 2009, 01:27) *
Более того(если захотеть), менять ее можно будет и из другой функции.
Я извиняюсь, что вмешиваюсь. Работать с этой переменной в другой функции можно будет только по указателю, который данная функция должна сообщить другой, но не по символическому имени переменной.
Я тут некоторое время назад пояснял одному (точнее одной smile.gif ) пользователю о типах переменных. Может интересно будет.
Go to the top of the page
 
+Quote Post
singlskv
сообщение Jan 26 2009, 21:29
Сообщение #13


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(rezident @ Jan 26 2009, 23:40) *
Работать с этой переменной в другой функции можно будет только по указателю,
который данная функция должна сообщить другой, но не по символическому имени переменной.

Я это и имел в виду.("менять ее можно будет...")

Цитата(sonycman @ Jan 27 2009, 00:07) *
А мне тут недавно говорили, что статические локальные переменные инициализируются при первом заходе в содержащую их функцию.
И совершенно не в стартапе.

Вас обманули... smile.gif

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

Ну и главное что память под такую переменную уже будет отведена компилятором, те к моменту первого
запуска ее адрес будет постоянным.
Go to the top of the page
 
+Quote Post
sonycman
сообщение Jan 26 2009, 21:51
Сообщение #14


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Цитата(singlskv @ Jan 27 2009, 01:29) *
Вас обманули... smile.gif

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

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

Да, проверил - простые встроенные типы к моменту первого входа в функцию уже инициализированы.

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

То есть статические локальные объекты всё таки несут в себе определённый оверхед...
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Slash   Язык С, ARM - простые вопросы   Jan 21 2009, 15:17
- - aaarrr   Цитата(Slash @ Jan 21 2009, 18:17) Стоит ...   Jan 21 2009, 15:29
- - Demeny   Цитата(Slash @ Jan 21 2009, 18:17) Стоит ...   Jan 22 2009, 08:33
|- - aaarrr   Цитата(Demeny @ Jan 22 2009, 11:33) Прави...   Jan 22 2009, 09:09
|- - Demeny   Цитата(aaarrr @ Jan 22 2009, 12:09) Поясн...   Jan 22 2009, 10:20
- - aaarrr   Для отладки глобальные переменные наоборот удобнее...   Jan 22 2009, 11:29
|- - Demeny   Цитата(aaarrr @ Jan 22 2009, 14:29) Для о...   Jan 22 2009, 12:35
||- - aaarrr   Цитата(Demeny @ Jan 22 2009, 15:35) Всё э...   Jan 22 2009, 12:48
||- - singlskv   Цитата(Demeny @ Jan 22 2009, 15:35) Это с...   Jan 23 2009, 00:27
||- - Demeny   Цитата(singlskv @ Jan 23 2009, 03:27) В к...   Jan 23 2009, 07:34
||- - A. Fig Lee   Цитата(singlskv @ Jan 22 2009, 19:27) В к...   Jan 23 2009, 19:06
|- - VladimirYU   Цитата(aaarrr @ Jan 22 2009, 14:29) Для о...   Jan 22 2009, 12:52
|- - zltigo   Цитата(VladimirYU @ Jan 22 2009, 14:52) К...   Jan 22 2009, 13:05
|- - aaarrr   Цитата(VladimirYU @ Jan 22 2009, 15:52) Д...   Jan 22 2009, 13:05
- - sergeeff   Это скорее организационная проблема. Один человек ...   Jan 22 2009, 15:14
|- - zltigo   Цитата(sergeeff @ Jan 22 2009, 17:14) Это...   Jan 22 2009, 17:14
- - rezident   Я бы предложил спорщикам уточнить, для какой облас...   Jan 23 2009, 00:46
|||||- - Dima_G   Цитата(singlskv @ Jan 27 2009, 01:29) Я э...   Jan 28 2009, 10:21
|||||- - A. Fig Lee   Цитата(Dima_G @ Jan 28 2009, 05:21) Локал...   Jan 28 2009, 14:45
||||- - sonycman   Цитата(singlskv @ Jan 27 2009, 00:27) Пер...   Jan 26 2009, 21:07
|||- - singlskv   Цитата(A. Fig Lee @ Jan 26 2009, 20:55) 2...   Jan 26 2009, 19:45
|||- - A. Fig Lee   Цитата(singlskv @ Jan 26 2009, 14:45) Вот...   Jan 26 2009, 22:07
|||- - zltigo   Цитата(A. Fig Lee @ Jan 27 2009, 01:07) О...   Jan 26 2009, 22:52
|||- - singlskv   Цитата(A. Fig Lee @ Jan 27 2009, 01:07) Н...   Jan 26 2009, 22:52
|||- - A. Fig Lee   Цитата(singlskv @ Jan 26 2009, 17:52) ага...   Jan 26 2009, 23:46
||- - zltigo   Цитата(A. Fig Lee @ Jan 26 2009, 17:20) Т...   Jan 26 2009, 15:22
|- - Dog Pawlowa   Цитата(Demeny @ Jan 26 2009, 12:58) Попро...   Jan 26 2009, 10:45
|- - _Pasha   Цитата(Dog Pawlowa @ Jan 26 2009, 13:45) ...   Jan 26 2009, 11:13
|- - Dog Pawlowa   Цитата(_Pasha @ Jan 26 2009, 14:13) Есть ...   Jan 26 2009, 15:10
|- - _Pasha   Цитата(Dog Pawlowa @ Jan 26 2009, 18:10) ...   Jan 26 2009, 15:23
|- - zltigo   Цитата(_Pasha @ Jan 26 2009, 18:23) Один ...   Jan 26 2009, 15:25
- - Goodefine   Я, вот, по простому спрошу... Допустим, имеем обра...   Jan 23 2009, 19:09
|- - A. Fig Lee   Цитата(Goodefine @ Jan 23 2009, 14:09) Я,...   Jan 24 2009, 03:01
|- - VladimirYU   Цитата(A. Fig Lee @ Jan 24 2009, 06:01) п...   Jan 24 2009, 08:23
|- - zltigo   Цитата(A. Fig Lee @ Jan 24 2009, 05:01) п...   Jan 24 2009, 08:47
|- - _Pasha   Цитата(zltigo @ Jan 24 2009, 11:47) Их до...   Jan 24 2009, 14:43
|- - A. Fig Lee   Цитата(zltigo @ Jan 24 2009, 03:47) Опять...   Jan 24 2009, 17:14
|- - zltigo   Цитата(A. Fig Lee @ Jan 24 2009, 20:14) н...   Jan 24 2009, 17:50
|- - A. Fig Lee   Цитата(zltigo @ Jan 24 2009, 12:50) Ага, ...   Jan 25 2009, 13:43
- - Serj78   Можно, я свои 5 копеек вставлю? Иногда , на мало...   Jan 24 2009, 08:14
- - A. Fig Lee   вот правильный стандард - C++: The zeroinitializa...   Jan 27 2009, 14:42
|- - zltigo   Цитата(A. Fig Lee @ Jan 27 2009, 17:42) в...   Jan 27 2009, 16:10
||- - A. Fig Lee   Цитата(zltigo @ Jan 27 2009, 11:10) Вы, к...   Jan 27 2009, 16:23
|- - singlskv   Цитатакстати, я все никак не добьюсь - речь о C ил...   Jan 27 2009, 22:27
|- - A. Fig Lee   Цитата(singlskv @ Jan 27 2009, 17:27) Ну ...   Jan 27 2009, 23:44
- - rezident   Модератор. Тема закрыта по просьбе топикстартера.   Feb 2 2009, 21:01


Closed TopicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 22:28
Рейтинг@Mail.ru


Страница сгенерированна за 0.01581 секунд с 7
ELECTRONIX ©2004-2016