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

Язык С, ARM - простые вопросы

В качестве примера, пусть есть некий программный автомат который чего-нить там куда-нить отсылает/пишет/итд

Так вот у него есть функции или глобальные переменные видимые из вне которые запускают действие, и есть

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

куча ГЛОБАЛЬНЫХ но невидимых из вне переменных которые содержат в себе все внутреннее состояние автомата.

Такой модуль вполне независим и множество таких модулей может работать в одной проге не мешая друг другу,

нужно только описать "Конвенцию..." по входным и выходным параметрам.

Вот об этом и речь ! Именно такой стиль ведения проекта мне, например, не нравится.

Предположим, Ваш модуль реализует некий программный автомат который чего-нить отсылает/пишет/итд, например, в UART. Всё внутреннее своё состояние он хранит в ГЛОБАЛЬНЫХ статических переменных.

Теперь мне нужно прикрутить в проект второй UART с той же функциональностью, третий, четвёртый ... И вообще - я, как менеджер проекта, не знаю, сколько у заказчика будет UART-ов. Как мне Ваш модуль с минимальными доработками несколько раз включить в проект ?

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


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

Теперь мне нужно прикрутить в проект второй UART с той же функциональностью, третий, четвёртый ... И вообще - я, как менеджер проекта, не знаю, сколько у заказчика будет UART-ов. Как мне Ваш модуль с минимальными доработками несколько раз включить в проект ?
Что-то я не понял затруднений. Статические переменные объявленные внутри функции имеют область видимости в пределах этой функции. Статические переменные объявленные вне какой-либо функции имеют область видимости в пределах данного модуля. Разве не так?

Могу конечно ошибаться, но по-моему singlskv имел в виду как раз такой случай. Глобальная переменная (объявленная вне тела функции) типа static имеет область видимости в пределах данного модуля. Никто не мешает дублировать эти модули в требуемых количествах. Хотя конечно же, если модуль состоит из одной функции, то разумнее было бы объявить эти переменные как static, но внутри самой функции.

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


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

Могу конечно ошибаться, но по-моему singlskv имел в виду как раз такой случай. Глобальная переменная (объявленная вне тела функции) типа static имеет область видимости в пределах данного модуля. Никто не мешает дублировать эти модули в требуемых количествах. Хотя конечно же, если модуль состоит из одной функции, то разумнее было бы объявить эти переменные как static, но внутри самой функции.
примерно это я и имел в виду,

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

а вот если несколько функций в модуле работают с одной статической переменной, то без глобальных определений никак не обойтись,

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

 

Я вот совсем теперь не понимаю за что ратует Demeny,

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

возможно речь о том что не нужно к ним обращаться напрямую ? то есть нужно предоставить интерфейс через вызов функций ?

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

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


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

В качестве примера, пусть есть некий программный автомат который чего-нить там куда-нить отсылает/пишет/итд

Так вот у него есть функции или глобальные переменные видимые из вне которые запускают действие, и есть

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

куча ГЛОБАЛЬНЫХ но невидимых из вне переменных которые содержат в себе все внутреннее состояние автомата.

Такой модуль вполне независим и множество таких модулей может работать в одной проге не мешая друг другу,

нужно только описать "Конвенцию..." по входным и выходным параметрам.

 

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

 

доступ ко всем можно организовать через проперти механизм (get/set).

 

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

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


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

Я, вот, по простому спрошу...

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

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

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


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

Я, вот, по простому спрошу...

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

 

правильно будет использовать глобальные переменные.

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

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


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

Можно, я свои 5 копеек вставлю?

 

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

 

Частный случай этого описал Goodefine двумя постами выше.

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


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

правильно будет использовать глобальные переменные.

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

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

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


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

пойнт в том, что их много быть не должно.

Опять :( пустые рекомендации. Их должно быть столько, сколько надо.

Да, сложно представить консерваторию, где ..

Несколько каналов связи. За каждым свои настройки, состояния, буфера. Просто нужно поднять протокол, ну возьмем что-нибудь простое классическое 70x годов прошлого века LAPB/MLP/X.25. Вашими образами - все должно играть по одной партитуре, хотя музыканты вообще сидят в разных городах и правят друг друга по сбоящему каналу связи. Вполне обычная задача для периферийного контроллера. Начинайте расширять свои представления о жизни в которой есть не только "контролеры светодиодов".   

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


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

Их должно быть столько, сколько надо.
Тема из разряда "что лучше : лог."0" или лог."1" . Автору - лечиться водкой до исчезновения состояния вопроса. Одну и ту же задачу можно решить более чем одним способом, критерий правильности которого лежит вне постановки решаемой задачи.

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


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

Опять :( пустые рекомендации. Их должно быть столько, сколько надо.

 

Несколько каналов связи. За каждым свои настройки, состояния, буфера. Просто нужно поднять протокол, ну возьмем что-нибудь простое классическое 70x годов прошлого века LAPB/MLP/X.25. Вашими образами - все должно играть по одной партитуре, хотя музыканты вообще сидят в разных городах и правят друг друга по сбоящему каналу связи. Вполне обычная задача для периферийного контроллера. Начинайте расширять свои представления о жизни в которой есть не только "контролеры светодиодов".   

 

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

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

должны бы вызыватся скажем через функцию с хендлом, скажем.

 

я се предстваляю TCP/IP где все глобальное - все данные сокетов и т.д.

:(

 

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

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


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

но все они в глобальном спейсе - плохой дизайн.

Ага, все они в стеке это даже не "дизайн" это просто бред.

 

глобально может быть виден номер канала

 

Упаси бог! "номер канала" ака указатель на конкретную структуру это как раз есть совершенно интимное дело функций работающими с данными каналов.

 

P.S.

 

 

Вы похоже совершенно путаете локальные переменные, глобальные, и области видимости глобальных. 

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


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

Ага, все они в стеке это даже не "дизайн" это просто бред.

 

 

 

Упаси бог! "номер канала" ака указатель на конкретную структуру это как раз есть совершенно интимное дело функций работающими с данными каналов.

 

P.S.

 

 

Вы похоже совершенно путаете локальные переменные, глобальные, и области видимости глобальных. 

 

Кроме стека есть еще хип. ето совсем не значит что переменные в хипе - глобальные.

И видмость их ограничена, глобальные переменные видны отовсюду.

если вы обьявили переменную из кучи и сделали ее static в С - она глобальной не будет,

несмотря на то, что не на стеке

 

Так, как я говорил - пишется подавляющее большинство програм.

 

Кстати, как вы к елементам структуры канала обращаетесь, если

Изменено пользователем A. Fig Lee

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


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

Я вот совсем теперь не понимаю за что ратует Demeny ...

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

1) Если Ваш конечный автомат, или другой программный модуль (функция) хранит своё внутреннее состояние в статических или глобальных переменных, он тут же становится непригодным для многопоточного использования, проще говоря, становится "non-reenterable", во всяком случае, Вам придётся прибегнуть к специальным ухищрениям навроде синхронизации, чтобы использование Ваших функций в многопоточном приложении не вызвало крах всего приложения. Также она не может быть безопасно вызвана в качестве обработчика прерывания.

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

2) Ваш модуль в составе программы может вообще оказаться невостребованным (ну нет у клиента 8 UART-ов, заложенных по максимуму ...), однако память под буфера и прочие настройки Вы уже зарезервировали статически. Или же Ваш модуль нужен только на этапе инициализации - один раз при старте системы, а память занята уже "навсегда" ...

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

4) С точки зрения проектирования удобно представлять себе отдельную функцию, как законченный функциональный блок ("черный ящик") с входными и выходными параметрами. Это позволяет отлаживать функцию отдельно от остальных. Использование глобальных переменных размывает это понятие, поскольку, как ни крути, поведение функции зависит от поведения остальной части программы. Вот и будем ломать голову при отладке, какого же рожна глобальная переменная имеет "не то" значение, какое должно быть, и какая собака его испортила. Придётся бросить отладку текущей функции и заняться поиском "собаки". :unsure:

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


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

1) Если Ваш конечный автомат, или другой программный модуль (функция) хранит своё внутреннее состояние в статических или глобальных переменных, он тут же становится непригодным....

 

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

 

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

 

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

 

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

 

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

 

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

 

 

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

 

 

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


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

Гость
Эта тема закрыта для публикации ответов.
×
×
  • Создать...