Данный код компилируется в C, но сбой в С++.
int main()
{
const int x; /* uninitialized const compiles in C but fails in C++*/
}
В чем причина и причина изменения с C на С++?
Данный код компилируется в C, но сбой в С++.
int main()
{
const int x; /* uninitialized const compiles in C but fails in C++*/
}
В чем причина и причина изменения с C на С++?
См. спецификацию в приложении совместимости C.1.6:
7.1.6 [см. также 3.5]
Изменить: объекты const должны быть инициализированы в С++, но могут быть оставлены неинициализированными в C
Обоснование: Объект const нельзя назначить так, чтобы он был инициализирован для хранения полезного значения.
Влияние на оригинальную функцию: Удаление семантически четко определенной функции.
Сложность преобразования: Семантическая трансформация.
Насколько широко используется: Редко.
Обратите внимание, что существует законное использование неинициализированного объекта с непрерывным хранением с константным контентом: его адрес можно использовать и использовать как уникальный ключ для обозначения уровней рекурсии в рекурсивной функции. Это несколько неясно, но стоит отметить. C делает это эффективным, в то время как С++ требует, чтобы вы теряли время и размер кода при его инициализации. (Теоретически компилятор мог бы определить, что значение никогда не используется и не оптимизирует инициализацию, но поскольку вы обходите указатель, это будет довольно сложно доказать.)
Ключевое слово const
было введено в C на C89 в 1989 году, но было с С++ с момента его создания в 1983 году. Таким образом, он был "backported" от С++ до C.
Семантика инициализации, как правило, различна в C и С++. Хотя большую часть времени они "просто делают то, что вы ожидаете", бывают случаи, когда различия становятся весьма важными. С++ действительно не является надмножеством C в конце концов.
Например, в С++ вы не можете:
goto x;
int i = 3;
x:
puts("Hello, world");
Но это вполне законно в C.
В стандарте 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 без инициализации и внешней связи, бесполезно, поэтому кодер должен был добавить ее по ошибке.