Есть ли const в C? - PullRequest
       40

Есть ли const в C?

49 голосов
/ 09 марта 2011

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

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

Ответы [ 10 ]

54 голосов
/ 09 марта 2011

Нет синтаксических различий между 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 */
13 голосов
/ 09 марта 2011

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

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

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

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

8 голосов
/ 09 марта 2011

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

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

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

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

5 голосов
/ 09 марта 2011

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

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

Соответствующий экстракт:

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

2 голосов
/ 09 марта 2011

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

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

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

2 голосов
/ 09 марта 2011

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

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

1 голос
/ 09 марта 2011

В 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 подчиняются соответствующим правилам области видимости.

1 голос
/ 09 марта 2011

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

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

1 голос
/ 09 марта 2011

Да, в C. есть ключевое слово const. Оно существует с C90.

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

...