C++ семантика `static const` vs` const`

В С++, в частности, каковы семантические различия между:

static const int x = 0 ;

и

const int x = 0 ;

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

Ответ 1

В области файлов разницы в С++ нет. const делает внутреннюю привязку по умолчанию, а все глобальные переменные имеют статическое время жизни. Но первый вариант имеет такое же поведение в C, что может быть хорошей причиной для его использования.

Внутри функции вторая версия может быть вычислена из параметров, в C или С++ она не должна быть константой времени компиляции, как требуется для некоторых других языков.

Внутри класса, в основном то же, что и для функций, значение экземпляра const может быть вычислено в ctor-initializer-list. A static const устанавливается во время инициализации запуска и остается неизменным для остальной части программы. (Примечание: код для членов static выглядит несколько иначе, потому что объявление и инициализация разделяются.)

Помните, что в С++ const означает только для чтения, а не константа. Если у вас есть указатель на const, то другие части программы могут изменить значение, пока вы не смотрите. Если переменная была определена с помощью const, то никто не может ее изменить после инициализации, но инициализация может быть произвольно сложной.

Ответ 2

C++ 17 стандартный черновик для const подразумевает static в области видимости файла

Это цитата для того, что было упомянуто по адресу: fooobar.com/info/54468/...

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 нет?

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

Подробно объяснено на: Что означает "постоянная статика" в C и C++?

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