На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
  
> Простой вопрос про static , найти ответ не могу в книгах
    Привет всем!
    У меня тут вопрос вроде бы простой возник : Чем отличаются статические(static) глобальные переменные от простых глобальных переменных.
      Тем же, чем статические функции (не методы класса) отличаются от просто функций - они имеют internal linkage.
      Т.е. в разных модулях могут быть переменные с одинаковым именем. Для нестатических переменных такое не прокатит.
        Если объявляешь переменную вне функции без квалификаторов, то переменная поумолчанию делается статической.

        Добавлено
        Цитата Hryak @
        Т.е. в разных модулях могут быть переменные с одинаковым именем. Для нестатических переменных такое не прокатит.

        Что-то я не сталкивался с таким. Интересно, а если в третьем модуле будет extern ссылка на переменную которая содержится одновременно в двух других модулях, то из какого модуля она залинкуется?

        Добавлено
        Я замечал только одно отличие - если объявить переменную со словом static и не использовать её, то компилятор выдаёт предупреждение "not referenced".
          ну так столкнись :) проверь - минутное дело
            Объявляя глобальную переменную статической ее нельзя будет вызвать извне данного модуля.
              Цитата GreenGen @
              Привет всем!
              У меня тут вопрос вроде бы простой возник : Чем отличаются статические(static) глобальные переменные от простых глобальных переменных.


              Статические переменные
              Статические переменные, в отличие от глобальных, неизвестны вне своей функции или файла, и сохраняют свои значения между вызовами. Это очень полезней создании обобщенных функции и библиотек функций, которые могут использовать другими программистами. Статические переменные отличаются как от локальных, так и от глобальных переменных.
              Локальные статические переменные
              Если локальная переменная объявлена с помощью спецификатора static, компилятор выделит для нее постоянное место хранения, как и для глобальной переменной Принципиальное отличие локальной статической переменной от глобальной состоит в том, что первая остается доступной лишь внутри своего блока. Проще говоря, локальная статическая переменная — это локальная переменная, сохраняющая свои значения между вызовами функции.
              Такие переменные очень полезны при создании изолированных функций, поскольку между вызовами их можно использовать в других частях программы. Если бы статических переменных не было, пришлось бы применять глобальные переменные, порождая неизбежные побочные эффекты. Примером удачного применения статических переменных является генератор чисел, который порождает новое число, используя предыдущее значение. Для хранения этого числа можно было бы использовать глобальную переменную, однако при каждом новом вызове ее пришлось бы объявлять заново, постоянно проверяя, не конфликтует ли она с другими глобальными переменными. Применение статической переменной легко решает эту проблему.
              ExpandedWrap disabled
                int series(void)
                {
                    static int series_num;
                    series_num = series_num+23;
                    return series_num;
                }

              В этом примере переменная series_num продолжает существовать между вызовами функции, а локальная переменная каждый раз создавалась бы при входе и уничтожалась при выходе из функции. Таким образом, каждый вызов функции series () порождает новый элемент ряда, используя предыдущее значение и не прибегая к глобальной переменной.
              Локальную статическую переменную можно инициализировать. Начальное значе¬ние присваивается лишь один раз, а не при каждом входе в блок, как это происходит с локальными переменными. Например, в приведенной ниже версии функции se¬ries () переменная eeries_num инициализируется числом 100.
              ExpandedWrap disabled
                int series(void)
                {
                   static int series_nuiti = 100;
                   series_num = series_num+23;
                   return series_num;
                }

              Теперь ряд будет всегда начинаться с числа 123. Хотя во многих приложениях это вполне приемлемо, обычно генераторы чисел предоставляют пользователю право выбора начального значения. Для этого можно сделать переменную series_num глобальной. Однако именно для того, чтобы избежать этого, и были созданы статические переменные. Это приводит ко второму способу использования статических переменных.
              Глобальные статические переменные
              Применение спецификатора static к глобальной переменной заставляет компилятор создать глобальную переменную, видимую только в пределах текущего файла. Несмотря на то что эта переменная остается глобальной, в других файлах она не существует. Следовательно, изменить ее значение путем вмешательства извне невозможно. Это предотвращает побочные эффекты. В некоторых ситуациях, в которых локальные статические переменные оказываются недостаточными, можно создать небольшой файл, содержащий лишь функции, которые используют конкретную глобальную статическую переменную, отдельно скомпилировать его и применять без риска возникновения побочных эффектов.
              Чтобы проиллюстрировать применение глобальной статической переменной, перепишем генератор чисел из предыдущего раздела таким образом, чтобы начальное значение задавалось при вызове функции series_start(). Весь файл, содержащий функции eeriest), series_start () и series_num(), показан ниже.
              ExpandedWrap disabled
                /* Все функции должны находиться в одном и том же файле.  */
                static int series_num;
                void series_start(int seed);
                int series(void);
                 
                int series(void) {
                   series_num = series_num+23 ;
                   return series_num;
                }
                /* Инициализация переменной series_num */
                void series_start(int seed) {
                   series_num = seed;
                }

              Вызов функции series_start() инициализирует генератор чисел. После этого следующий элемент ряда порождается новым вызовом функции seriesO.
              К сведению: локальные статические переменные видимы лишь в пределах блока, где они объявлены, а глобальные статические переменные — в пределах файла. Если поместить функции series() и series() и start() в библиотеку, то переменная series_num станет невидимой. Более того, в программе можно объявить новую переменную series_num (разумеется, в другом файле). По существу модификатор static позволяет создавать переменные, видимые лишь в пределах функций не порождая побочных эффектов.
              Модификатор static позволяет скрывать часть программы от других модулей Это чрезвычайно важно при разработке больших и сложных программ.
              ExpandedWrap disabled
                2 GreenGen, надеюсь я заслужил +  :lol:
                Цитата polyglott @
                Если объявляешь переменную вне функции без квалификаторов, то переменная поумолчанию делается статической.

                Без каких квалификаторов? :wacko:
                А как её сделать нестатической тогда? Написать nostatic int g;, что ли? :lol:

                Цитата
                Интересно, а если в третьем модуле будет extern ссылка на переменную которая содержится одновременно в двух других модулях, то из какого модуля она залинкуется?

                Ни из какого. Линковка не пройдет.
                  Цитата Hryak @
                  А как её сделать нестатической тогда? Написать nostatic int g;, что ли?

                  Да, я ступил.

                  Цитата Hryak @
                  Без каких квалификаторов

                  Ну там всякие квалификаторы-шмалификаторы, типа const, static, auto, extern...
                    Цитата polyglott @
                    Ну там всякие квалификаторы-шмалификаторы, типа const, static, auto, extern...

                    Понятно.

                    Но квалификаторами являются только const и volatile. Остальное - спецификаторы. ;)
                      Вобщем как я понял если просто глобальная переменная то её область видимости 1 фаил в котором она объявлена а static глобальная переменная её видно во всех файлах проекта.

                      Как я понял они различаются областью видимости?
                        Цитата GreenGen @
                        Вобщем как я понял если просто глобальная переменная то её область видимости 1 фаил в котором она объявлена а static глобальная переменная её видно во всех файлах проекта.

                        Да. Тьфу ты. :wall: Нет, конечно же.
                        Пора на покой.
                        Сообщение отредактировано: Hryak -
                          Цитата GreenGen @
                          Вобщем как я понял если просто глобальная переменная то её область видимости 1 фаил в котором она объявлена а static глобальная переменная её видно во всех файлах проекта.

                          Наоборот. static глобальная переменная видна только в том файле, в котором объявлена, просто глобальная --- во всех.
                            GreenGen вообщем прочитай в книге про internal linkage (атрибут статик) и external linkage, и как проходит процесс компиляции и компоновки.
                              Цитата Hryak @
                              Написать nostatic int g;, что ли?
                              Так нельзя! Это безграмотно! Надо писать nonstatic.
                                Цитата Hryak @
                                А как её сделать нестатической тогда? Написать nostatic int g;, что ли?

                                по умолчанию функции итак имеют не статик спецификатор, а именно extern

                                Цитата Adil @
                                Так нельзя! Это безграмотно! Надо писать nonstatic.

                                тоесть грамотно ;) ,надо писать extern или ничего.
                                  Цитата Sazabis @
                                  по умолчанию функции итак имеют не статик спецификатор, а именно extern
                                  Не могут они иметь extern, поскольку extern используется только в объявлениях (declaration), а фунция (не прототип, а именно функция) - это определение (definition).
                                    Цитата -Daemon- @
                                    Не могут они иметь extern, поскольку extern используется только в объявлениях (declaration), а фунция (не прототип, а именно функция) - это определение (definition).

                                    и ? что, функция не может быть external linkage ?
                                      Sazabis объявление, но не определение ;)

                                      Добавлено
                                      Возможно я не правильно понял твою реплику.
                                        Цитата Adil @
                                        Цитата Hryak @
                                        Написать nostatic int g;, что ли?
                                        Так нельзя! Это безграмотно! Надо писать nonstatic.

                                        :whistle:

                                        -Added
                                        Цитата Sazabis @
                                        Цитата Hryak @
                                        А как её сделать нестатической тогда? Написать nostatic int g;, что ли?

                                        по умолчанию функции итак имеют не статик спецификатор, а именно extern

                                        Зачем слова из контекста вырываешь? Перечитай сквотированное мной перед этими словами.
                                          Цитата Hryak @
                                          Зачем слова из контекста вырываешь? Перечитай сквотированное мной перед этими словами.

                                          значит не понял, и опять перечитал не понял )) Вопрос какой нибуть был вообще ?
                                          Цитата Hryak @
                                          Написать nostatic int g;, что ли?

                                          написать extern int g; extern это проивоположность static.
                                            Цитата Sazabis @
                                            Цитата Hryak @
                                            Зачем слова из контекста вырываешь? Перечитай сквотированное мной перед этими словами.

                                            значит не понял, и опять перечитал не понял )) Вопрос какой нибуть был вообще ?

                                            Повторяю содержание первой части поста #7:
                                            <<<<<<<<<<
                                            Цитата polyglott @
                                            Если объявляешь переменную вне функции без квалификаторов, то переменная поумолчанию делается статической.

                                            Без каких квалификаторов? :wacko:
                                            А как её сделать нестатической тогда? Написать nostatic int g;, что ли? :lol:
                                            >>>>>>>>>>

                                            Во-первых, речь шла про переменные, а не функции.
                                            Во-вторых, extern вообще не при делах, т.к. определение не может содержать extern, про что тут уже говорили.
                                            В-третьих, я знаю, что функции по умолчанию имеют внешнюю линковку :tong: .
                                              Цитата Hryak @
                                              определение не может содержать extern, про что тут уже говорили.

                                              :blink:
                                                Цитата LPBOY @
                                                Цитата Hryak @
                                                определение не может содержать extern, про что тут уже говорили.

                                                :blink:

                                                Цитата
                                                A declaration is a definition unless it declares a function without specifying the function's body (dcl.fct.def), it contains the extern specifier (dcl.stc) or a linkage-specification*
                                                  :no: :no: :no:
                                                  Цитатка не до конца. :rolleyes:
                                                  Цитата

                                                  A declaration is a definition unless it declares a function without specifying the function’s body (8.4), it
                                                  contains the extern specifier (7.1.1) or a linkage-specification (7.5) and neither an initializer nor a
                                                  function-body,


                                                  ExpandedWrap disabled
                                                    extern int x = 1; // определение, компилится нормально
                                                    extern int fn() // определение, компилится нормально
                                                    {
                                                        return 1;
                                                    }
                                                    Уболтали. :yes:
                                                      Цитата LPBOY @
                                                      extern int fn() // определение, компилится нормально
                                                      :blink: Век живи, век учись...
                                                        Цитата Hryak @
                                                        А как её сделать нестатической тогда? Написать nostatic int g;, что ли? :lol:
                                                        >>>>>>>>>>

                                                        Подумай! Как глобальная переменная может быть нестатической? Все глобальные переменные - статические.
                                                        По отношению к глобальным переменным слово static приобретает просто иной смысл, чем по отношению к локальным
                                                          Цитата gryz @
                                                          По отношению к глобальным переменным слово static приобретает просто иной смысл, чем по отношению к локальным

                                                          Спасибо за просвещение, не знал этого. :wub:
                                                            gryz тогда встречный вопрос по поводу линковки. Почему если в хедер файле объявить переменную и инклудить ее в две разные единицы трансляции - возникает ошибка линковщика. Если же прописать спецификатор static, т.е. явно указать способ линковки, - то ествественно ошибка исчезает.
                                                              Цитата -Daemon- @
                                                              gryz тогда встречный вопрос по поводу линковки. Почему если в хедер файле объявить переменную и инклудить ее в две разные единицы трансляции - возникает ошибка линковщика. Если же прописать спецификатор static, т.е. явно указать способ линковки, - то ествественно ошибка исчезает.

                                                              Этот static никаким образом не относится к статику для локальных переменных и членов классов.
                                                              static для глобальных переменных как раз и делает их уникальными для каждой единицы трансляции.
                                                              Фактически в этом случае компилятор создает несколько независимых глобальных переменных по одной для каждой единицы трансляции
                                                                gryz я это все понимаю. Но ты вот написал выше:
                                                                Цитата
                                                                Как глобальная переменная может быть нестатической? Все глобальные переменные - статические.
                                                                Если все глобальные переменные - статические (в глобальной области видимости), значит по идее они имеют internal linkage. Тогда почему пример, который я приводил выше, без ключевого слова static, приводит к ошибке линковщика?
                                                                  -Daemon-
                                                                  Тут надо смотреть на то, как ты понимаешь понятие "статическая переменная". :)
                                                                  ---
                                                                  When modifying a variable or function at file scope, the static keyword specifies that the variable or function has internal linkage (its name is not visible from outside the file in which it is declared).
                                                                  ----
                                                                  и
                                                                  ---
                                                                  Objects and variables defined outside all blocks have static lifetime and external linkage by default. A global object or variable that is explicitly declared as static has internal linkage.

                                                                  ---
                                                                  говоря, что переменная статическая. Я не имею ввиду, что у нее internal linkage, а имею ввиду ее "статическое" поведение
                                                                    -Daemon-, ну понятно же, что просто путаница в терминологии: "статический" по отношению к времени жизни и к области видимости. Хотя gryz неприминул попытаться Hryak'а на этом подловить.
                                                                      gryz ок.
                                                                      Adil я сам запутался :)
                                                                        Цитата Adil @
                                                                        -Daemon-, ну понятно же, что просто путаница в терминологии: "статический" по отношению к времени жизни и к области видимости. Хотя gryz неприминул попытаться Hryak'а на этом подловить.

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

                                                                        Добавлено
                                                                        Меня огорчило как на polyglott набросились :)
                                                                          Цитата gryz @
                                                                          статическая переменная - это скорее переменная, имеющая характерное время жизни, чем характерную область видимости.

                                                                          Скорее - это завист от контекста употребления.

                                                                          Добавлено
                                                                          Цитата Adil @
                                                                          Меня огорчило как на polyglott набросились
                                                                          , хм, а меня - порадовало, что не на меня так набросились. Будь оптимистом. :D
                                                                            Цитата Adil @
                                                                            хм, а меня - порадовало, что не на меня так набросились. Будь оптимистом. :D

                                                                            Ну на тебя то за то?
                                                                            nonstatic - неплохое ключевое слово.
                                                                            можно было бы и попользоваться им :)))
                                                                              Цитата Adil @
                                                                              -Daemon-, ну понятно же, что просто путаница в терминологии: "статический" по отношению к времени жизни и к области видимости. Хотя gryz неприминул попытаться Hryak'а на этом подловить.

                                                                              "Попытка - не пытка" © ЛПБ :lool:

                                                                              Цитата gryz
                                                                              Все таки, у меня в процессе работы с с++ сложилось мнение, что статическая переменная - это скорее переменная, имеющая характерное время жизни, чем характерную область видимости.

                                                                              Так это твое мнение.
                                                                              Моё мнение - "Статическая переменная - это переменная объявленная с использованием ключевого слова static".
                                                                              Сомневаюсь, что мое определение хуже твоего, потому что оно универсальней. Просто смысл зависит от контекста (кстати, перечитай ветку и найди хоть одно упоминание того, что речь шла про твой контекст - т.е. про локальные переменные)
                                                                              Я не применяю такое определение, когда контест неясен - в этом случае всегда добавляю к выражению "глобальная"/"локальная".
                                                                              А то, что ты называешь "статической переменной", называю "переменной со статическим временем жизни", если речь идет именно про время жизни.
                                                                              Сообщение отредактировано: Hryak -
                                                                              1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                                                              0 пользователей:


                                                                              Рейтинг@Mail.ru
                                                                              [ Script execution time: 0.1394 ]   [ 15 queries used ]   [ Generated: 17.06.26, 21:37 GMT ]