Есть ли const в C?

Этот вопрос может быть наивным, но:

  • есть const Ключевое слово в C?
  • с какой версии?
  • Существуют ли какие-либо семантические и / или синтаксические различия между const в C и C++?

10 ответов

Решение

Там нет синтаксических различий между 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 */

Ответы на первые два вопроса здесь: Const in C

Да, между семантикой довольно много различий const в C и C++.

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

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

Да, есть const ключевое слово. Он был добавлен как часть стандарта 1989 года.

Что касается совместимости, вот параграф из Harbison & Steele, 5-е издание:

Объявление верхнего уровня, которое имеет спецификатор типа const но явный класс хранения не считается static в С ++ но extern в C. Чтобы оставаться совместимым, изучите верхний уровень const объявления и предоставляют явный класс хранения. В C++ строковые константы неявно const; они не в C.

Да, const был там, по крайней мере, начиная с ANSI C (он же C89).

Это, безусловно, появляется в моей копии "Язык программирования Си (2-е издание)", Kernighan & Ritchie (опубликовано в 1988 году).

Соответствующая выписка:

const а также volatile свойства являются новыми со стандартом ANSI. Цель const заключается в объявлении объектов, которые могут быть помещены в постоянную память, и, возможно, для расширения возможностей для оптимизации.

Два других различия:

Да. const есть в C, от C89.

Вот хорошее прочтение о поведении ключевого слова const в Си.

Семантика в C отличается от C++, например

unsigned const a = 10;
unsigned A[a];

в области видимости файла будет действительным в C++, но не в C.

Согласно ESR, const был добавлен в проект предлагаемого стандарта ANSI C. Резюме Эрик Жигуре по ANSI C от 1987 года подтверждает это.

РЕДАКТИРОВАТЬ: Это похоже на сам черновик - поиск "3.5.3 квалификаторов типов".

В C есть ключевое слово "const", и оно уже долгое время. Если переменная обозначена как "const", запись в нее запрещена. Кроме того, в некоторых средах переменные, объявленные как "const", могут находиться в другом сегменте данных, чем другие переменные. Этот сегмент данных может предлагать аппаратную защиту от записи, а для встроенных систем может храниться в ПЗУ или флэш-памяти, а не в ОЗУ (очень важное отличие на некоторых процессорах, которые имеют намного больше ПЗУ или флэш-памяти, чем ОЗУ - например, 128 КБ флэш-памяти и 3,5 КБ ОЗУ или 2 КБ ПЗУ и 96 байт ОЗУ).

Обратите внимание, что компилятор, как правило, не делает никаких выводов о значениях "const" или выражениях, в которых они содержатся. Если я скажу "const char foo[] = "Hello";" а затем позже сделайте ссылку на foo[1], компилятор загрузит значение (которое, скорее всего, будет 'e') из того места, где хранится foo [], и использует загруженное значение. Иногда это полезно для того, чтобы значения могли быть исправлены в скомпилированном образе кода, но иногда это просто трата кода.

Если вы хотите определить число как "заменяемую" константу во время компиляции, лучшим способом, по крайней мере для целочисленных констант, может быть использование "enum". Например, "enum {woozle=19;}" приведет к замене 19 на "woozle" во всем коде. Обратите внимание, что в отличие от текстовых подстановок; Объявления enum подчиняются соответствующим правилам области видимости.

Да, есть const Ключевое слово в C. Он был там с C90.

Синтаксически это может происходить в тех же местах, что и в C++. Семантически, это немного более мягко, IIRC.

Другие вопросы по тегам