Подтвердить что ты не робот

Существует ли const в C?

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

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

Ответ 1

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

void foo(int a[const]);

что эквивалентно

void foo(int *const a);

объявления. С++ не поддерживает такой синтаксис.

Семантические различия существуют. Как уже отмечал @Ben Voigt, в C const объявления не генерируют постоянные выражения, т.е. В C вы не можете использовать объект const int в метке case, как ширину битового поля или размер массива в объявление не-VLA-массива (все это возможно в С++). Кроме того, объекты const имеют внешнюю связь по умолчанию в C (внутренняя связь в С++).

Там, по крайней мере, еще одна семантическая разница, о которой Бен не упомянул. Правила Const-correctness языка С++ поддерживают следующее стандартное преобразование

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 */

Как правило, при работе с многоуровневыми указателями С++ говорит, что вы можете добавить const-квалификацию в любой глубине косвенности, если вы также добавляете const-qualification вплоть до верхнего уровня.

В C вы можете только добавить const-qualification к типу, указанному указателем верхнего уровня, но не глубже.

int **pp = 0;
int *const *cpp = pp; /* OK in C */

int ***ppp = 0;
int **const *cppp = ppp; /* OK in C */

Другим проявлением того же основного общего принципа является то, как правила const-correctness работают с массивами на C и С++. В С++ вы можете сделать

int a[10];
const int (*p)[10] = &a; // OK in C++

Попытка сделать то же самое в C приведет к ошибке

int a[10];
const int (*p)[10] = &a; /* ERROR in C */

Ответ 2

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

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

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

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

Ответ 3

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

Что касается совместимости, здесь абзац из Харбисона и Стил, 5-е издание:

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

Ответ 4

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

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

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

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

Ответ 5

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

Ответ 7

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

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

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

Ответ 8

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

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

Ответ 10

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

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

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