Нет синтаксических различий между C и C ++ в отношении ключевого слова const
, кроме довольно неясного: в C (начиная с C99) вы можете объявить параметры функции как
void foo(int a[const]);
, что эквивалентно
void foo(int *const a);
декларация. C ++ не поддерживает такой синтаксис.
Существуют и семантические различия. Как уже отмечал @Ben Voigt, в объявлениях C const
не создаются постоянные выражения, т. Е. В C вы не можете использовать объект const int
в метке case
, в качестве ширины битового поля или в качестве размера массива в объявление массива без VLA (все это возможно в C ++). Кроме того, const
объекты имеют внешнюю связь по умолчанию в C (внутренняя связь в C ++).
Есть по крайней мере еще одно семантическое различие, о котором Бен не упомянул. Правила константности языка C ++ поддерживают следующее стандартное преобразование
int **pp = 0;
const int *const *cpp = pp; // OK in C++
int ***ppp = 0;
int *const *const *cppp = ppp; // OK in C++
Эти инициализации недопустимы в C.
int **pp = 0;
const int *const *cpp = pp; /* ERROR in C */
int ***ppp = 0;
int *const *const *cppp = ppp; /* ERROR in C */
Как правило, при работе с многоуровневыми указателями C ++ говорит, что вы можете добавить const-квалификацию на любой глубине косвенности, если вы также добавляете const-квалификацию вплоть до верхнего уровня.
В C вы можете добавить const-квалификацию только к типу, указанному указателем верхнего уровня, но не глубже.
int **pp = 0;
int *const *cpp = pp; /* OK in C */
int ***ppp = 0;
int **const *cppp = ppp; /* OK in C */
Другим проявлением того же базового общего принципа является то, как правила константной корректности работают с массивами в C и C ++. В C ++ вы можете сделать
int a[10];
const int (*p)[10] = &a; // OK in C++
Попытка сделать то же самое в C приведет к ошибке
int a[10];
const int (*p)[10] = &a; /* ERROR in C */