const в C против const в C ++ - PullRequest
12 голосов
/ 22 мая 2011

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

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

В чем причина и причина перехода с C на C ++?

Ответы [ 4 ]

14 голосов
/ 22 мая 2011

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

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

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

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

Эффект на исходный элемент: Удаление семантически четко определенного элемента.

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

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

12 голосов
/ 22 мая 2011

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

5 голосов
/ 22 мая 2011

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

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

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

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

Но это совершенно законно в C.

3 голосов
/ 22 мая 2011

Стандарт ISO гласит (в 8.5 [dcl.init] параграф 9 ):

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...