Const в C vs const в С++

Данный код компилируется в C, но сбой в С++.

int main()
{
   const int x; /* uninitialized const compiles in C but fails in C++*/
}

В чем причина и причина изменения с C на С++?

Ответ 1

См. спецификацию в приложении совместимости C.1.6:

7.1.6 [см. также 3.5]

Изменить: объекты const должны быть инициализированы в С++, но могут быть оставлены неинициализированными в C

Обоснование: Объект const нельзя назначить так, чтобы он был инициализирован для хранения полезного значения.

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

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

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

Ответ 2

Обратите внимание, что существует законное использование неинициализированного объекта с непрерывным хранением с константным контентом: его адрес можно использовать и использовать как уникальный ключ для обозначения уровней рекурсии в рекурсивной функции. Это несколько неясно, но стоит отметить. C делает это эффективным, в то время как С++ требует, чтобы вы теряли время и размер кода при его инициализации. (Теоретически компилятор мог бы определить, что значение никогда не используется и не оптимизирует инициализацию, но поскольку вы обходите указатель, это будет довольно сложно доказать.)

Ответ 3

Ключевое слово const было введено в C на C89 в 1989 году, но было с С++ с момента его создания в 1983 году. Таким образом, он был "backported" от С++ до C.

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

Например, в С++ вы не можете:

goto x;
int i = 3;
x:
puts("Hello, world");

Но это вполне законно в C.

Ответ 4

В стандарте ISO говорится (в 8.5 [dcl.init] пункт 9):

Если для объекта не задан инициализатор, а объект имеет значение (возможно, cv-qualified) тип класса не-POD (или его массив), объект должен быть инициализирован по умолчанию; если объект имеет const-qual type, тип базового класса должен иметь объявленный пользователем конструктор по умолчанию.

если вы попробуете тот же пример после изменения к этому:

int main()
{
   /*Unless explicitly declared extern, a const object does not have
 external linkage and must be initialized*/
   extern const int x; 
   return 0;
}

он будет скомпилирован. Таким образом, это объясняет необходимость принудительной реализации этой ошибки для С++, объявляя const vars без инициализации и внешней связи, бесполезно, поэтому кодер должен был добавить ее по ошибке.