Есть ли 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++).

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

другим проявлением того же основного общего принципа является то, как правила const-корректности работают с массивами в 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 в C

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

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

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


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

что касается совместимости, вот абзац из Harbison & Steele, 5-е издание:

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

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


да const существует, по крайней мере, с ANSI C (он же C89).

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

соответствующая выдержка:

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


сематика в C отличается от сематики в C++, e.g

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

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


да. const есть в C, из C89.

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


Да, есть const ключевое слово в с. Он там с С90.

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


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

изменить: это похоже на сам проект - поиск "3.5.3 квалификаторы типов".


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

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

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