|
|
  |
Язык С, ARM - простые вопросы |
|
|
|
Jan 21 2009, 15:17
|
Местный
  
Группа: Участник
Сообщений: 202
Регистрация: 10-04-05
Из: Санкт-Петербург
Пользователь №: 4 011

|
Здравствуйте! Стоит ли пользоваться глобальными переменными и можно ли без них обойтись? В книгах пишут, что глобальные переменные - плохой тон, можно запутаться. А если программа строится в виде задач в бесконечном цикле: Код while (1) { Task1(); Task2(); Task3(); } Как обмениваться сообщениями между задачами? Мне понравилась система глобальных флагов - данные готовы к отправке, данные приняты, какое-то действие завершено и т.д. Как без них?
|
|
|
|
|
Jan 21 2009, 15:29
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Slash @ Jan 21 2009, 18:17)  Стоит ли пользоваться глобальными переменными и можно ли без них обойтись? В книгах пишут, что глобальные переменные - плохой тон, можно запутаться. В книгах часто глупости пишут. Глобальными переменными пользоваться стоит, обойтись без них затруднительно. Главное не заменять ими локальные где не надо. Цитата(Slash @ Jan 21 2009, 18:17)  Мне понравилась система глобальных флагов - данные готовы к отправке, данные приняты, какое-то действие завершено и т.д. Как без них? Нормальная система.
|
|
|
|
|
Jan 22 2009, 08:33
|

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

|
Цитата(Slash @ Jan 21 2009, 18:17)  Стоит ли пользоваться глобальными переменными и можно ли без них обойтись? В книгах пишут, что глобальные переменные - плохой тон, можно запутаться. Правильно пишут. Пока проект небольшой (до 10 файлов на С) - это несущественно, а в больших проектах (особенно многопоточных) обилия глобальных переменных лучше избегать - замучаетесь с отладкой. Кроме того, следование этому принципу побуждает программиста к грамотной структуризации кода, в котором каждая функция выполняет строго определённую задачу, имеет набор входных и выходных данных, которые, собственно, и передаются через параметры функции, а не выносятся в глобальные переменные. Цитата(Slash @ Jan 21 2009, 18:17)  А если программа строится в виде задач в бесконечном цикле: Код while (1) { Task1(); Task2(); Task3(); } Как обмениваться сообщениями между задачами? Мне понравилась система глобальных флагов - данные готовы к отправке, данные приняты, какое-то действие завершено и т.д. Как без них? Например, так. Код while (1) { int Msg1, Msg2, Msg3; Task1(&Msg1, &Msg2); Task2(&Msg3, &Msg2); Task3(&Msg1); }
--------------------
Сделано в Китае. Упаковано в России.
|
|
|
|
|
Jan 22 2009, 10:20
|

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

|
Цитата(aaarrr @ Jan 22 2009, 12:09)  Поясните, пожалуйста, каким это образом глобальные переменные мешают отладке? При их обилии, они запутывают логику выполнения программы (и без того запутанную  ). Поскольку инициализируется переменная в одном месте, модифицируется в другом, а используется ещё в десятке разных мест (на то она и глобальная переменная). Также им нужно придумывать уникальные имена, а при сходной функциональности эти имена будут примерно такие - Counter27, Sigma7, Delta18, Sum88, что тоже не добавляет читабельности коду.
--------------------
Сделано в Китае. Упаковано в России.
|
|
|
|
|
Jan 22 2009, 12:35
|

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

|
Цитата(aaarrr @ Jan 22 2009, 14:29)  Для отладки глобальные переменные наоборот удобнее, так как видны всегда. Иногда даже лучше временно заменить локальные переменные на глобальные, чтобы видеть результаты промежуточных вычислений. Это справедливо, если проект маленький. В большом проекте отладку каждого модуля (функции) удобно производить отдельно, особенно если они написаны разными людьми. Для этого нужно уметь быстро собрать модуль и проверить (отладить) его функционирование. А если он усеян декларациями "extern ...", то мало того, что для его запуска потребуется определять все эти переменные локально, так ещё и сделает этот модуль нелинкуемым в составе проекта, если ту или иную глобальную переменную удалят другие разработчики. Всё это влечёт за собой геморрой необходимость ведения Конвенции по глобальным переменным в рамках проекта, и т. п. И ещё важный момент. Если Вы в своём модуле "нечаянно" измените логику работы с глобальным объектом, остальные разработчики об этом так и не узнают, только программа из-за возможной Вашей ошибки в целом может оказаться в один момент неработоспособной, и простыми средствами "поймать за руку" поломавшийся модуль не представляется возможным, повторюсь, особенно в многопоточном приложении. Зато если Вы поменяете перечень вызываемых параметров, их тип или количество ( "ну, не использую я более переменную Sum --> удаляю её из перечня параметров моей функции!" ) - это тут же выяснится ещё на этапе компиляции-линковки, и остальные разработчики смогут внести изменения в свои тексты. Цитата(aaarrr @ Jan 22 2009, 14:29)  Попытка использовать локальную переменную там, где нужна глобальная, запутает программу гораздо сильнее. Поэтому книжные утверждения, что де "плохой тон" следует отметать как бредовые. Нужно просто разумно использовать и те, и другие. Там, где действительно нужна глобальная переменная, заменить её локальной невозможно в принципе - локальная будет "не видна" остальным. Никто ведь и не говорит, что от них нужно отказаться совсем. Речь идёт о том, что использовать глобальную переменную там, где запросто можно обойтись локальной - это плохой стиль программирования, "дурной тон". -------------------------- Такая же история с оператором "goto". В принципе, в С можно без него обойтись. Но есть случаи, где его применение улучшает читабельность и логическую структуру кода, проще говоря, удобно. Однако заменять все циклы оператором "goto" - это "дурной тон".
--------------------
Сделано в Китае. Упаковано в России.
|
|
|
|
|
Jan 22 2009, 12:48
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Demeny @ Jan 22 2009, 15:35)  Всё это влечёт за собой геморрой необходимость ведения Конвенции по глобальным переменным в рамках проекта, и т. п. А как без нее вообще можно обойтись? Если глобальные объекты используются в качестве интерфейсов между различными частями проекта, то они в любом случае должны быть согласованы. Но это далеко не единственный вариант, глобальные переменные могут использоваться и только в пределах модуля, а здесь никаких ограничений нет. Цитата(Demeny @ Jan 22 2009, 15:35)  Никто ведь и не говорит, что от них нужно отказаться совсем. Речь идёт о том, что использовать глобальную переменную там, где запросто можно обойтись локальной - это плохой стиль программирования, "дурной тон". Разумеется, но обратная ситуация - не менее, если не более дурной.
|
|
|
|
|
Jan 22 2009, 12:52
|
Местный
  
Группа: Свой
Сообщений: 426
Регистрация: 5-04-07
Из: Санкт-Петербург
Пользователь №: 26 782

|
Цитата(aaarrr @ Jan 22 2009, 14:29)  Для отладки глобальные переменные наоборот удобнее, так как видны всегда. Иногда даже лучше временно заменить локальные переменные на глобальные, чтобы видеть результаты промежуточных вычислений. Для этого достаточно одной глобальной переменной, которая удаляется после окончания отладки. Как правило, даже в сложном, но грамотно спроектированном проекте, глобальных переменных единицы.
|
|
|
|
|
Jan 22 2009, 17:14
|

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

|
Цитата(sergeeff @ Jan 22 2009, 17:14)  Это скорее организационная проблема. Это ВООБЩЕ НЕ ПРОБЛЕМА и уж тем более не организационая. Либо глобальные данные принципиально нужны, либо нет. Цитата При коллективной работе глобальные переменные раскиданные по ... Хоть при коллективной, хоть любой другой РАБОТЕ а бездумном бумагомарательстве, глобальные данные, структуры, поля, биты описываются ЕДИНОЖДЫ в хидерах. Дополнительно для доступа к данным c целью сокрытия ненужных подробностей можно иметь макросы/функции. И никакого кошмара.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 23 2009, 00:27
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(Demeny @ Jan 22 2009, 15:35)  Это справедливо, если проект маленький. ИМХО, это совсем не так, ну посмотрите на Linux например... Цитата В большом проекте отладку каждого модуля (функции) удобно производить отдельно, особенно если они написаны разными людьми. Для этого нужно уметь быстро собрать модуль и проверить (отладить) его функционирование. А если он усеян декларациями "extern ...", то мало того, что для его запуска потребуется определять все эти переменные локально, так ещё и сделает этот модуль нелинкуемым в составе проекта, если ту или иную глобальную переменную удалят другие разработчики. Всё это влечёт за собой геморрой необходимость ведения Конвенции по глобальным переменным в рамках проекта, и т. п. По моему Вы смешиваете в одном понятии совсем разные вещи, глобальные это те переменные которые заводятся вне функций, все... (утрированно конечно) Вы можете сделать их доступными для других модулей(например через extern), а можете и не делать, более того Вы можете сделать их доступными для одной части других модулей и недоступными для другой(например через препроцессор, ну или еще много как). "Конвенции по глобальным переменным в рамках проекта" не относяться ко всем глобальным переменным(если конечно это не было целью). В качестве примера, пусть есть некий программный автомат который чего-нить там куда-нить отсылает/пишет/итд Так вот у него есть функции или глобальные переменные видимые из вне которые запускают действие, и есть например глобальные переменные видимые из вне которые показывают состояние выполнения, а еще есть куча ГЛОБАЛЬНЫХ но невидимых из вне переменных которые содержат в себе все внутреннее состояние автомата. Такой модуль вполне независим и множество таких модулей может работать в одной проге не мешая друг другу, нужно только описать "Конвенцию..." по входным и выходным параметрам.
|
|
|
|
|
Jan 23 2009, 07:34
|

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

|
Цитата(singlskv @ Jan 23 2009, 03:27)  В качестве примера, пусть есть некий программный автомат который чего-нить там куда-нить отсылает/пишет/итд Так вот у него есть функции или глобальные переменные видимые из вне которые запускают действие, и есть например глобальные переменные видимые из вне которые показывают состояние выполнения, а еще есть куча ГЛОБАЛЬНЫХ но невидимых из вне переменных которые содержат в себе все внутреннее состояние автомата. Такой модуль вполне независим и множество таких модулей может работать в одной проге не мешая друг другу, нужно только описать "Конвенцию..." по входным и выходным параметрам. Вот об этом и речь ! Именно такой стиль ведения проекта мне, например, не нравится. Предположим, Ваш модуль реализует некий программный автомат который чего-нить отсылает/пишет/итд, например, в UART. Всё внутреннее своё состояние он хранит в ГЛОБАЛЬНЫХ статических переменных. Теперь мне нужно прикрутить в проект второй UART с той же функциональностью, третий, четвёртый ... И вообще - я, как менеджер проекта, не знаю, сколько у заказчика будет UART-ов. Как мне Ваш модуль с минимальными доработками несколько раз включить в проект ?
--------------------
Сделано в Китае. Упаковано в России.
|
|
|
|
|
Jan 23 2009, 15:10
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(Demeny @ Jan 23 2009, 12:34)  Теперь мне нужно прикрутить в проект второй UART с той же функциональностью, третий, четвёртый ... И вообще - я, как менеджер проекта, не знаю, сколько у заказчика будет UART-ов. Как мне Ваш модуль с минимальными доработками несколько раз включить в проект ? Что-то я не понял затруднений. Статические переменные объявленные внутри функции имеют область видимости в пределах этой функции. Статические переменные объявленные вне какой-либо функции имеют область видимости в пределах данного модуля. Разве не так? Могу конечно ошибаться, но по-моему singlskv имел в виду как раз такой случай. Глобальная переменная (объявленная вне тела функции) типа static имеет область видимости в пределах данного модуля. Никто не мешает дублировать эти модули в требуемых количествах. Хотя конечно же, если модуль состоит из одной функции, то разумнее было бы объявить эти переменные как static, но внутри самой функции.
|
|
|
|
|
Jan 23 2009, 15:57
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

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

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

|
Цитата(singlskv @ Jan 22 2009, 19:27)  В качестве примера, пусть есть некий программный автомат который чего-нить там куда-нить отсылает/пишет/итд Так вот у него есть функции или глобальные переменные видимые из вне которые запускают действие, и есть например глобальные переменные видимые из вне которые показывают состояние выполнения, а еще есть куча ГЛОБАЛЬНЫХ но невидимых из вне переменных которые содержат в себе все внутреннее состояние автомата. Такой модуль вполне независим и множество таких модулей может работать в одной проге не мешая друг другу, нужно только описать "Конвенцию..." по входным и выходным параметрам. отказать. как правило, почти всегда можно инкапсулировать глобальные переменные. доступ ко всем можно организовать через проперти механизм (get/set). польза явно осчущается когда работают человек 20 на одном проекте, чтоб не лезли шаловливыми ручками в чужой код.
--------------------
Верить нельзя никому, даже себе. Мне - можно.
|
|
|
|
|
Jan 23 2009, 19:09
|

Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 6-08-07
Из: Приднестровье, Тирасполь
Пользователь №: 29 581

|
Я, вот, по простому спрошу... Допустим, имеем обработчик некоторого прерывания, в котором надо быстро выполнить неотложные действия и установить один или несколько флагов, дабы потом, в основном цикле их неспешно обработать. Как правильно передать эти флаги в основной цикл не используя глобальных переменных?
Сообщение отредактировал Goodefine - Jan 23 2009, 19:11
--------------------
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
|
|
|
|
|
Jan 24 2009, 03:01
|

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

|
Цитата(Goodefine @ Jan 23 2009, 14:09)  Я, вот, по простому спрошу... Допустим, имеем обработчик некоторого прерывания, в котором надо быстро выполнить неотложные действия и установить один или несколько флагов, дабы потом, в основном цикле их неспешно обработать. Как правильно передать эти флаги в основной цикл не используя глобальных переменных? правильно будет использовать глобальные переменные. пойнт в том, что их много быть не должно. если их 60 килобайт, как тут пишут - скорее всего чтото не так в консерватории (общий случай сферического коня в ваккууме)
--------------------
Верить нельзя никому, даже себе. Мне - можно.
|
|
|
|
|
Jan 24 2009, 08:23
|
Местный
  
Группа: Свой
Сообщений: 426
Регистрация: 5-04-07
Из: Санкт-Петербург
Пользователь №: 26 782

|
Цитата(A. Fig Lee @ Jan 24 2009, 06:01)  правильно будет использовать глобальные переменные. пойнт в том, что их много быть не должно. если их 60 килобайт, как тут пишут - скорее всего чтото не так в консерватории (общий случай сферического коня в ваккууме) Да, сложно представить консерваторию, где в оркестре все музыканты играют по одной для всех партитуре и одновременно каждый норовит ее подправить на свой вкус.
|
|
|
|
|
Jan 24 2009, 08:47
|

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

|
Цитата(A. Fig Lee @ Jan 24 2009, 05:01)  пойнт в том, что их много быть не должно. Опять  пустые рекомендации. Их должно быть столько, сколько надо. Цитата(VladimirYU @ Jan 24 2009, 10:23)  Да, сложно представить консерваторию, где .. Несколько каналов связи. За каждым свои настройки, состояния, буфера. Просто нужно поднять протокол, ну возьмем что-нибудь простое классическое 70x годов прошлого века LAPB/MLP/X.25. Вашими образами - все должно играть по одной партитуре, хотя музыканты вообще сидят в разных городах и правят друг друга по сбоящему каналу связи. Вполне обычная задача для периферийного контроллера. Начинайте расширять свои представления о жизни в которой есть не только "контролеры светодиодов".
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 24 2009, 17:14
|

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

|
Цитата(zltigo @ Jan 24 2009, 03:47)  Опять  пустые рекомендации. Их должно быть столько, сколько надо. Несколько каналов связи. За каждым свои настройки, состояния, буфера. Просто нужно поднять протокол, ну возьмем что-нибудь простое классическое 70x годов прошлого века LAPB/MLP/X.25. Вашими образами - все должно играть по одной партитуре, хотя музыканты вообще сидят в разных городах и правят друг друга по сбоящему каналу связи. Вполне обычная задача для периферийного контроллера. Начинайте расширять свои представления о жизни в которой есть не только "контролеры светодиодов". ну - почему переменные глобальбые? настройки - для каждого канала (т.е. не глобальные), но все они в глобальном спейсе - плохой дизайн. глобально может быть виден номер канала - все. остальные пропертис - личное дело етого канала и должны бы вызыватся скажем через функцию с хендлом, скажем. я се предстваляю TCP/IP где все глобальное - все данные сокетов и т.д.  ето как кернел - который глобальный для взаимосвязи, остальное все в юзерленд
--------------------
Верить нельзя никому, даже себе. Мне - можно.
|
|
|
|
|
Jan 24 2009, 17:50
|

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

|
Цитата(A. Fig Lee @ Jan 24 2009, 20:14)  но все они в глобальном спейсе - плохой дизайн. Ага, все они в стеке это даже не "дизайн" это просто бред. Цитата глобально может быть виден номер канала Упаси бог! "номер канала" ака указатель на конкретную структуру это как раз есть совершенно интимное дело функций работающими с данными каналов. P.S. Вы похоже совершенно путаете локальные переменные, глобальные, и области видимости глобальных.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 25 2009, 13:43
|

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

|
Цитата(zltigo @ Jan 24 2009, 12:50)  Ага, все они в стеке это даже не "дизайн" это просто бред.
Упаси бог! "номер канала" ака указатель на конкретную структуру это как раз есть совершенно интимное дело функций работающими с данными каналов.
P.S.
Вы похоже совершенно путаете локальные переменные, глобальные, и области видимости глобальных. Кроме стека есть еще хип. ето совсем не значит что переменные в хипе - глобальные. И видмость их ограничена, глобальные переменные видны отовсюду. если вы обьявили переменную из кучи и сделали ее static в С - она глобальной не будет, несмотря на то, что не на стеке Так, как я говорил - пишется подавляющее большинство програм. Кстати, как вы к елементам структуры канала обращаетесь, если
Сообщение отредактировал A. Fig Lee - Jan 25 2009, 13:43
--------------------
Верить нельзя никому, даже себе. Мне - можно.
|
|
|
|
|
Jan 26 2009, 09:58
|

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

|
Цитата(singlskv @ Jan 23 2009, 18:57)  Я вот совсем теперь не понимаю за что ратует Demeny ... Попробую ещё раз пояснить преимущества локальных переменных перед глобальными, пусть даже и статическими, т. е. видимыми в пределах одного программного модуля. 1) Если Ваш конечный автомат, или другой программный модуль (функция) хранит своё внутреннее состояние в статических или глобальных переменных, он тут же становится непригодным для многопоточного использования, проще говоря, становится "non-reenterable", во всяком случае, Вам придётся прибегнуть к специальным ухищрениям навроде синхронизации, чтобы использование Ваших функций в многопоточном приложении не вызвало крах всего приложения. Также она не может быть безопасно вызвана в качестве обработчика прерывания. В случае локальных переменных всё безопасно - ведь у каждого потока свой стек, следовательно, каждый поток работает со своим уникальным набором переменных. 2) Ваш модуль в составе программы может вообще оказаться невостребованным (ну нет у клиента 8 UART-ов, заложенных по максимуму ...), однако память под буфера и прочие настройки Вы уже зарезервировали статически. Или же Ваш модуль нужен только на этапе инициализации - один раз при старте системы, а память занята уже "навсегда" ... 3) Доступ к локальным переменным осуществляется, как правило, быстрее, чем к глобальным (статическим), потому что любой оптимизирующий компилятор старается раскидать по возможности локальные переменные по регистрам процессора. 4) С точки зрения проектирования удобно представлять себе отдельную функцию, как законченный функциональный блок ("черный ящик") с входными и выходными параметрами. Это позволяет отлаживать функцию отдельно от остальных. Использование глобальных переменных размывает это понятие, поскольку, как ни крути, поведение функции зависит от поведения остальной части программы. Вот и будем ломать голову при отладке, какого же рожна глобальная переменная имеет "не то" значение, какое должно быть, и какая собака его испортила. Придётся бросить отладку текущей функции и заняться поиском "собаки".
--------------------
Сделано в Китае. Упаковано в России.
|
|
|
|
|
Jan 26 2009, 10:32
|

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

|
Цитата(Demeny @ Jan 26 2009, 12:58)  1) Если Ваш конечный автомат, или другой программный модуль (функция) хранит своё внутреннее состояние в статических или глобальных переменных, он тут же становится непригодным.... Либо с точностью до наоборот - ПРИГОДНЫМ. Конечный автомат получает указатель на структуру с котрой работать в данный момент и работает. Кроме того, опять, если нужны сколь нибудь реально-сложные автоматы в многопоточном приложении, то по любому он нужен и эти проблемы придется решать и отнюдь "просто используем локальные переменные". Цитата Вы уже зарезервировали статически. Статически-то зачем? Спросили сколько надо у менеджера памяти. А вот стек, который потребуется Вам для Вашего непрогнозируемого количества "UART-ов" Вы как раз скорее всего статически-то и выделите. Цитата 3) Доступ к локальным переменным осуществляется, как правило, быстрее, чем к глобальным (статическим) Из каждого "правила" есть исключения. Причем "как правило" они очень мешают жить. Цитата .. поведение функции зависит от поведения остальной части программы. Либо поведение этой функции ДОЛЖНО ЗАВИСЕТЬ от "остальной части" и тут Вас никакие ухищрения не заставят обойти эту зависимость. Либо НЕ зависят - в этом случае глубоко фиолетов глобальные или нет какие-то переменные, ибо в этом случае они по любому приватно находятся в пользовании одной функции.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 26 2009, 10:45
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(Demeny @ Jan 26 2009, 12:58)  Попробую ещё раз пояснить ... Этап системного проектирования, постановки задачи и разбиения задачи на подзадачи вообще-то присутствует? Вот и выбирается на этом этапе все, включая способы взаимодействия, ресурсы, особенности. В общем случае "глобальность против локальности" не имеет решения. Та же "реентерабельность". Почему printf не реентерабельный, не задумывались? Почему разработчики компиляторов не хотят осчастливить страждущих?
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Jan 26 2009, 14:20
|

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

|
Цитата(zltigo @ Jan 26 2009, 05:32)  Статически-то зачем? Спросили сколько надо у менеджера памяти. А вот стек, который потребуется Вам для Вашего непрогнозируемого количества "UART-ов" Вы как раз скорее всего статически-то и выделите.
Товарищи капиталисты, по-моему вы путаете теплое с мягким. Глобальное - то, что видно отовсюду и всегда живет (возможно спорно), Локальное - определено и живет в пределах обьекта к которому принадлежит. Пример - переменные обьявленные внутри функции - локальные для етой функции ( совсем не обязательно они должны быть на стеке), переменные обьявленные внутри класс/структуры - локальны для етих классов/структур и глобально (без структуры/класса) - невидимы. Могут размещатся в хипе, от етого глобальными не становятся.
--------------------
Верить нельзя никому, даже себе. Мне - можно.
|
|
|
|
|
Jan 26 2009, 17:55
|

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

|
Цитата(_Pasha @ Jan 26 2009, 09:49)  Статическое - это то, что видно только там, где надо, и всегда живет. Не путайте мертвое с пьяным  смотря о каких языках говорил - C или C++? 2. живет не всегда. например, обьявленная внутри функции - с момента обращения к функции. Цитата(zltigo @ Jan 26 2009, 10:22)  Это у Вас каша  из глобальности и области видимости, на что я уже сразу указывал. видимость переменной может быть и глобальной, но она являтся локальной - обьявить паблик мембер - член класса
--------------------
Верить нельзя никому, даже себе. Мне - можно.
|
|
|
|
|
Jan 26 2009, 19:45
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(A. Fig Lee @ Jan 26 2009, 20:55)  2. живет не всегда. например, обьявленная внутри функции - с момента обращения к функции. Живет она как раз всегда, а вот увидеть ее мы можем другой функцией только после обращения к фунцкии в которой она определена(а можем и не увидеть если не захотим...). Вот с вашей точки зрения в таком коде: Код void someFunc() { static unsigned char ch; ................ } переменная ch глобальная или локальная ? Разница между глобальными и локальными ИМХО, заключается в том что к глобальной(если захочу), могу обратиться из любой другой функции, а вот к локальной только из функции в которой она создана.
|
|
|
|
|
Jan 26 2009, 20:27
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(sonycman @ Jan 26 2009, 23:17)  А если статическая переменная локальная? Разве её инициализация будет производиться в стартапе? Переменная из моего предыдущего поста статическая и объявлена в теле функции, ее инициализация будет проведена в стартапе. Более того(если захотеть), менять ее можно будет и из другой функции.
|
|
|
|
|
Jan 26 2009, 20:40
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(singlskv @ Jan 27 2009, 01:27)  Более того(если захотеть), менять ее можно будет и из другой функции. Я извиняюсь, что вмешиваюсь. Работать с этой переменной в другой функции можно будет только по указателю, который данная функция должна сообщить другой, но не по символическому имени переменной. Я тут некоторое время назад пояснял одному (точнее одной  ) пользователю о типах переменных. Может интересно будет.
|
|
|
|
|
Jan 26 2009, 21:29
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(rezident @ Jan 26 2009, 23:40)  Работать с этой переменной в другой функции можно будет только по указателю, который данная функция должна сообщить другой, но не по символическому имени переменной. Я это и имел в виду.("менять ее можно будет...") Цитата(sonycman @ Jan 27 2009, 00:07)  А мне тут недавно говорили, что статические локальные переменные инициализируются при первом заходе в содержащую их функцию. И совершенно не в стартапе. Вас обманули...  Ну то есть, конечно, можно представить себе компилятор который будет так поступать, только это очень не эффективно. Ну и главное что память под такую переменную уже будет отведена компилятором, те к моменту первого запуска ее адрес будет постоянным.
|
|
|
|
|
Jan 26 2009, 21:51
|

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

|
Цитата(singlskv @ Jan 27 2009, 01:29)  Вас обманули...  Ну то есть, конечно, можно представить себе компилятор который будет так поступать, только это очень не эффективно. Ну и главное что память под такую переменную уже будет отведена компилятором, те к моменту первого запуска ее адрес будет постоянным. Да, проверил - простые встроенные типы к моменту первого входа в функцию уже инициализированы. С другой стороны - объект простого класса инициализируется всё таки уже внутри функции - с обработкой защёлки через __cxa_guard_acquire. Несмотря на то, что такие-же глобальные объекты создаются и инитятся в стартапе. Но не локальные статические. То есть статические локальные объекты всё таки несут в себе определённый оверхед...
|
|
|
|
|
Jan 26 2009, 22:07
|

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

|
Цитата(singlskv @ Jan 26 2009, 14:45)  Вот с вашей точки зрения в таком коде: Код void someFunc() { static unsigned char ch; ................ } переменная ch глобальная или локальная ? локальная ясен пень. увидеть нельзя ниоткуда, анлесс через мемори кастинг. вы братцы тут хаккеры ембедеры я гляжу собрались. через мемори - ето не глобальная переменная, ето читать участок памяти ok. из Си стандарда. Немного неправильно обозвал глобальные, да. Онако - время жизни статической переменной внутри функции определено со времени входа в функцию 6.2.4 Storage durations of objects 1 An object has a storage duration that determines its lifetime. There are three storage durations: static, automatic, and allocated. Allocated storage is described in 7.20.3. 2 The lifetime of an object is the portion of program execution during which storage is guaranteed to be reserved for it. An object exists, has a constant address,25) and retains its last-stored value throughout its lifetime.26) If an object is referred to outside of its lifetime, the behavior is undefined. The value of a pointer becomes indeterminate when the object it points to reaches the end of its lifetime. 3 An object whose identifier is declared with external or internal linkage, or with the storage-class specifier static has static storage duration. Its lifetime is the entire execution of the program and its stored value is initialized only once, prior to program startup. 4 An object whose identifier is declared with no linkage and without the storage-class specifier static has automatic storage duration. 5 For such an object that does not have a variable length array type, its lifetime extends from entry into the block with which it is associated until execution of that block ends in any way. (Entering an enclosed block or calling a function suspends, but does not end, execution of the current block.) If the block is entered recursively, a new instance of the object is created each time. The initial value of the object is indeterminate. If an initialization is specified for the object, it is performed each time the declaration is reached in the execution of the block; otherwise, the value becomes indeterminate each time the declaration is reached. 6 For such an object that does have a variable length array type, its lifetime extends from the declaration of the object until execution of the program leaves the scope of the declaration.27) If the scope is entered recursively, a new instance of the object is created each time. The initial value of the object is indeterminate.
--------------------
Верить нельзя никому, даже себе. Мне - можно.
|
|
|
|
|
Jan 26 2009, 23:46
|

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

|
Цитата(singlskv @ Jan 26 2009, 17:52)  ага, неправильно, и выделить нужно было другой текст: 3 An object whose identifier is declared with external or internal linkage, or with the storage-class specifier static has static storage duration. Its lifetime is the entire execution of the program and its stored value is initialized only once, prior to program startup.
Обращу Ваше внимание что в этом пункте вобще ничего не сказанно про место где декларируется static identifier ... енивей, глобальные переменные - стстические обьявленные в глобальном скопе. возражения есть? кстати, я все никак не добьюсь - речь о C или C++ ? раные языки, разное определение статик
--------------------
Верить нельзя никому, даже себе. Мне - можно.
|
|
|
|
|
Jan 27 2009, 14:42
|

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

|
вот правильный стандард - C++: The zeroinitialization (8.5) of all local objects with static storage duration (3.7.1) is performed before any other initialization takes place. A local object of POD type (3.9) with static storage duration initialized with constantexpressions is initialized before its block is first entered. An implementation is permitted to perform early initialization of other local objects with static storage duration under the same conditions that an implementation is permitted to statically initialize an object with static storage duration in namespace scope (3.6.2). Otherwise such an object is initialized the first time control passes through its declaration; such an object is considered initialized upon the completion of its initialization. If the initialization exits by throwing an exception, the initialization is not complete, so it will be tried again the next time control enters the declaration.если мы о C++ ( так как статик внутри функции). если о C, то там в принципе статик по барабану для длительности жизни. вопчем, я победил.
--------------------
Верить нельзя никому, даже себе. Мне - можно.
|
|
|
|
|
Jan 27 2009, 16:23
|

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

|
Цитата(zltigo @ Jan 27 2009, 11:10)  Вы, как выяснилось, не можете ни думать, ни понимать написанное. Бывает  . Товарищ Супермодератор - если у Вас нет возражений по существу, прошу держать себя в рамках. Или аргументы в студию
--------------------
Верить нельзя никому, даже себе. Мне - можно.
|
|
|
|
|
Jan 27 2009, 22:27
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата кстати, я все никак не добьюсь - речь о C или C++ ? раные языки, разное определение статик Ну вроде как и о том и о другом, и речь здесь велась в основном о "static storage duration", как о глобальных переменных а никак об области их видимости... Но если хотите продолжить: Цитата вот правильный стандард - C++: (8.5) of all local objects with static storage duration (3.7.1) is performed before any other initialization takes place. Но на этом конечно не будем зацикливаться... Посмотрим тут: Цитата A local object of POD type (3.9) with static storage duration initialized with constantexpressions is initialized before its block is first entered. An implementation is permitted to perform early initialization of other local objects with static storage duration under the same conditions that an implementation is permitted to statically initialize an object with static storage duration in namespace scope (3.6.2). Otherwise such an object is initialized the first time control passes through its declaration; such an object is considered initialized upon the completion of its initialization. If the initialization exits by throwing an exception, the initialization is not complete, so it will be tried again the next time control enters the declaration. Вот очень простой вопрос к Вам, если " exits by throwing an exception" произошел, то lifetime уже началась или еще нет ?
|
|
|
|
|
Jan 27 2009, 23:44
|

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

|
Цитата(singlskv @ Jan 27 2009, 17:27)  Ну вроде как и о том и о другом, и речь здесь велась в основном о "static storage duration", как о глобальных переменных а никак об области их видимости...
Но если хотите продолжить: Но на этом конечно не будем зацикливаться... Посмотрим тут: Вот очень простой вопрос к Вам, если "exits by throwing an exception" произошел, то lifetime уже началась или еще нет ? нет, не началась. начнется после успешной инициализации.. собственно, для Си кийворд статик можно опустить - глобал там ето обьявленные прям в теле программы, а статик влияет на визибилити онли
--------------------
Верить нельзя никому, даже себе. Мне - можно.
|
|
|
|
|
Jan 28 2009, 10:21
|
Местный
  
Группа: Свой
Сообщений: 279
Регистрация: 2-07-08
Из: Новосибирск
Пользователь №: 38 699

|
Цитата(singlskv @ Jan 27 2009, 01:29)  Я это и имел в виду.("менять ее можно будет...") Вас обманули...  Ну то есть, конечно, можно представить себе компилятор который будет так поступать, только это очень не эффективно. Ну и главное что память под такую переменную уже будет отведена компилятором, те к моменту первого запуска ее адрес будет постоянным. Локальная статическая переменная будет проинициализирована при первом входе входе в область ее видимости. Память под статическую переменную выделяется на этапе линковки - соответственно живет она все время жизни программы.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|