C ++ семантика `статическое const` против` const`


149

В частности, в C ++, каковы семантические различия, например:

static const int x = 0 ;

и

const int x = 0 ;

для обоих в staticкачестве связи и классом хранения спецификатора (т.е. внутри и снаружи функции).


7
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, то никто не может изменить ее после инициализации, но инициализация все еще может быть сколь угодно сложной.


1
Есть ли что-то, называемое областью файлов Я только что проверил 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область видимости файла

Это цитата для того, что было упомянуто по адресу: https://stackoverflow.com/a/3709257/895245

C ++ 17 n4659 стандартная редакция 6.5 "Программа и связь":

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-объекта. Эта функция позволяет пользователю помещать константные объекты в исходные файлы, включенные в более чем одну единицу перевода.

Влияние на исходную функцию: изменение семантики четко определенной функции.

Сложность конвертации: семантическая трансформация.

Насколько широко используются: редко.

Смотрите также: Почему const подразумевает внутреннюю связь в C ++, а в C нет?

Что вы, скорее всего, хотите сделать вместо заголовков

Подробно объяснено на: Что означает «const static» в C и C ++?

  • до C ++ 17: externв заголовке, определение в файле cpp
  • пост C ++ 17: встроенная переменная в заголовке

Спасибо, хотя я не думаю, что это шанс в C ++ 17 по сравнению даже с C ++ 98, и вопрос был задан в 2010 году. Более того, ваш ответ касается только static как спецификатора связывания (в области пространства имен) и вопрос, заданный специально о семантике в разных контекстах.
Клиффорд

@ Clifford да, определенно старше C ++ 17, просто лень читать все стандарты ;-) Уточню часть области видимости файла.
Сиро Сантилли 郝海东 冠状 病 六四 事件 法轮功
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.