staticэто, вероятно, наиболее перегруженное ключевое слово в C ++. Значение вашего кода широко варьируется в зависимости от того, находится ли он в области пространства имен, в области класса или в области функции. Вы можете уточнить это.
2010 г.,
1
@Sbi: Я думал, что уже сделал. Область действия функции (где это спецификатор класса хранения) и область действия файла (где это спецификатор связи). Члены класса и переменные в пространстве имен конкретно не интересуют меня в этом вопросе, хотя, если кто-то чувствует, что есть интересное различие, не стесняйтесь охватить это тоже.
Клиффорд
@ Clifford: извините, я пропустил эти последние слова. Однако, это показало непонимание с вашей стороны: В C ++, область файла является сферой пространства имен. Если вы объявите что-либо вне какого-либо пространства имен, оно просто будет принадлежать глобальному пространству имен (и доступно через префикс ::без идентификатора впереди). Мне не известны какие-либо значимые различия между глобальным пространством имен и любым вложенным в него пространством имен. Там, конечно, нет никаких staticобъектов.
СБи
1
связь отличается от видимости , используя их взаимозаменяемо, вы будете путать людей, с которыми вы разговариваете, и, вероятно, также себя.
Бен Фойгт
1
@Ben, @sbi: Я не собирался предполагать, что область файла и статическая связь были одинаковыми, просто статическая связь подразумевает область файла. В этом смысле область действия (или видимость) является атрибутом статической и внешней связи, а не синонимом ни того, ни другого. Я чувствую, что первоначальный вопрос остается ясным и правильно сформулированным, и что мы просто обсуждаем комментарии, сделанные в ответ на несколько снисходительное замечание sbi. Здесь мы обсуждаем неточную семантику английского языка, а не мое понимание, поэтому я думаю, что мы можем остановиться.
Клиффорд
Ответы:
128
В области видимости файлов нет никакой разницы в C ++. constделает внутреннюю связь по умолчанию, и все глобальные переменные имеют статическое время жизни. Но первый вариант имеет такое же поведение в C, так что это может быть хорошей причиной для его использования.
Внутри функции вторая версия может быть вычислена из параметров. В C или C ++ она не должна быть константой времени компиляции, как это требуется в некоторых других языках.
Внутри класса в основном то же самое, что и для функций. constЗначение экземпляра может быть вычислено в ctor-initializer-list . A static constустанавливается во время инициализации запуска и остается неизменным для остальной части программы. (Примечание: код для staticчленов выглядит немного иначе, потому что объявление и инициализация разделены.)
Помните, что в C ++ constозначает только чтение , а не константа . Если у вас есть указатель на, constто другие части программы могут изменить значение, пока вы не смотрите. Если переменная была определена с помощью const, то никто не может изменить ее после инициализации, но инициализация все еще может быть сколь угодно сложной.
Есть ли что-то, называемое областью файлов Я только что проверил 3,3 доллара, и я думаю, что самым близким является «область пространства имен». Правильно ли мое понимание? Стандарт C ++ 03 упоминает область действия файла только в Приложениях
Chubsdad
2
Я бы предположил, что область видимости файла - это артефакт компоновщика, а не компилятора, поэтому он может не привлекать большого внимания в языковом стандарте. Строго говоря, это, вероятно, "область действия модуля компиляции".
Клиффорд
8
+1 для фразы «const означает только чтение, а не константу», то есть «Компилятор, если вы видите кого-то, пытающегося изменить эту вещь const, лает очень громко». Это причина того, что что-то может быть постоянным и изменчивым одновременно.
Дэн
5
Это скорее «Компилятор, если вы видите, что я пытаюсь изменить эту постоянную вещь (или даю кому-то еще разрешение на это)», лает очень громко. В большинстве constслучаев применяется к представлению переменной, а не к самой переменной, кто-то другой может иметь представление не constтой же переменной, и компилятор будет молчать, когда они ее изменят.
Бен Фойгт
1
@Ben: Просто для ясности, C ++ 0x не удаляет это конкретное использование const, но constexprвместо этого можно использовать новое (и в других сценариях). На самом деле стандарт C ++ 0x расширяет возможности использования constв этом сценарии и до нецелых «литеральных типов». Я думаю, что я бы предпочел использовать constexprдля этих случаев, так как вы все равно нарушите обратную совместимость с компиляторами до C ++ 0x.
Майкл Берр
4
Черновик стандарта C ++ 17 constподразумевает staticобласть видимости файла
3 Имя, имеющее область имен (6.3.6), имеет внутреннюю связь, если это имя
(3.1) - переменная, функция или шаблон функции, которые явно объявлены статическими; или,
(3.2) - не встроенная переменная энергонезависимого типа с константной квалификацией, которая явно не объявлена как внешняя и не объявлена ранее как имеющая внешнюю связь; или
(3.3) - член данных анонимного объединения.
Совместимость Приложения C (информативная), C.1.2. Пункт 6: «основные понятия» дает обоснование, почему это было изменено с C:
6.5 [также 10.1.7]
Изменение: имя области видимости файла, которая явно объявлена как const, а не явно объявлена как extern, имеет внутреннюю связь, тогда как в C она будет иметь внешнюю связь.
Обоснование: поскольку const-объекты могут использоваться в качестве значений во время перевода в C ++, эта функция призывает программистов предоставлять явный инициализатор для каждого const-объекта. Эта функция позволяет пользователю помещать константные объекты в исходные файлы, включенные в более чем одну единицу перевода.
Влияние на исходную функцию: изменение семантики четко определенной функции.
Спасибо, хотя я не думаю, что это шанс в C ++ 17 по сравнению даже с C ++ 98, и вопрос был задан в 2010 году. Более того, ваш ответ касается только static как спецификатора связывания (в области пространства имен) и вопрос, заданный специально о семантике в разных контекстах.
Клиффорд
@ Clifford да, определенно старше C ++ 17, просто лень читать все стандарты ;-) Уточню часть области видимости файла.
static
это, вероятно, наиболее перегруженное ключевое слово в C ++. Значение вашего кода широко варьируется в зависимости от того, находится ли он в области пространства имен, в области класса или в области функции. Вы можете уточнить это.::
без идентификатора впереди). Мне не известны какие-либо значимые различия между глобальным пространством имен и любым вложенным в него пространством имен. Там, конечно, нет никакихstatic
объектов.Ответы:
В области видимости файлов нет никакой разницы в C ++.
const
делает внутреннюю связь по умолчанию, и все глобальные переменные имеют статическое время жизни. Но первый вариант имеет такое же поведение в C, так что это может быть хорошей причиной для его использования.Внутри функции вторая версия может быть вычислена из параметров. В C или C ++ она не должна быть константой времени компиляции, как это требуется в некоторых других языках.
Внутри класса в основном то же самое, что и для функций.
const
Значение экземпляра может быть вычислено в ctor-initializer-list . Astatic const
устанавливается во время инициализации запуска и остается неизменным для остальной части программы. (Примечание: код дляstatic
членов выглядит немного иначе, потому что объявление и инициализация разделены.)Помните, что в C ++
const
означает только чтение , а не константа . Если у вас есть указатель на,const
то другие части программы могут изменить значение, пока вы не смотрите. Если переменная была определена с помощьюconst
, то никто не может изменить ее после инициализации, но инициализация все еще может быть сколь угодно сложной.источник
const
случаев применяется к представлению переменной, а не к самой переменной, кто-то другой может иметь представление неconst
той же переменной, и компилятор будет молчать, когда они ее изменят.const
, ноconstexpr
вместо этого можно использовать новое (и в других сценариях). На самом деле стандарт C ++ 0x расширяет возможности использованияconst
в этом сценарии и до нецелых «литеральных типов». Я думаю, что я бы предпочел использоватьconstexpr
для этих случаев, так как вы все равно нарушите обратную совместимость с компиляторами до C ++ 0x.Черновик стандарта C ++ 17
const
подразумеваетstatic
область видимости файлаЭто цитата для того, что было упомянуто по адресу: https://stackoverflow.com/a/3709257/895245
C ++ 17 n4659 стандартная редакция 6.5 "Программа и связь":
Совместимость Приложения C (информативная), C.1.2. Пункт 6: «основные понятия» дает обоснование, почему это было изменено с C:
Смотрите также: Почему const подразумевает внутреннюю связь в C ++, а в C нет?
Что вы, скорее всего, хотите сделать вместо заголовков
Подробно объяснено на: Что означает «const static» в C и C ++?
extern
в заголовке, определение в файле cppисточник