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

Константная корректность в C vs С++

Я понимаю, что такое const correctness, и мой вопрос не в том, что такое const correctness. Поэтому я не ожидаю объяснений или ссылок на С++ - FAQ для этого.

Мои вопросы:

  • Каковы семантические различия между const в C и const в С++? и
  • В чем причина разницы?

Цитаты из соответствующих стандартов, которые делают различия четкими, было бы неплохо иметь.

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

Кажется, я не помню причину этих (особая благодарность, если вы можете дать аргументацию), но, с моей точки зрения, я помню:

  • константные переменные в С++ имеют внутреннюю привязку по умолчанию, а в C - внешняя связь по умолчанию;
  • const объекты могут использоваться как значения времени компиляции в С++, но не могут использоваться как значения времени компиляции в C;
  • Указатели на строковые литералы должны быть char const* в С++, но в C это может быть char*.

Что мне не хватает?

4b9b3361

Ответ 1

В дополнение к различиям, которые вы цитируете, и различиям в библиотеке, которые Стив Джессоп упоминает,

char* p1;
char const* const* p2 = &p1;

является законным в С++, но не в C. Исторически это происходит потому, что C изначально разрешено:

char* p1;
char const** p2 = &p1;

Незадолго до принятия стандарта кто-то понял, что это пробивает дыру в const безопасности (поскольку *p2 теперь можно назначить char const*, что приводит к тому, что p1 присваивается a char const*); с нет реального времени для углубленного анализа проблемы, комитет С запретил любые дополнительный const, отличный от верхнего уровня const. (I.e. &p1 может быть присваивается char ** или char **const, но не к char const** ни a char const* const*.) Комитет С++ сделал дальнейшее анализ, понял, что проблема была только тогда, когда a const уровень сопровождался уровнем не const и выработал необходимый формулировка. (См. §4.4/4 в стандарте.)

Ответ 2

В объявлениях 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.

Ответ 3

Причина некоторых из этих различий заключается в том, чтобы позволить нам избавиться от макросов препроцессора, что было одним из ранних целей дизайна Bjarne.

В C мы могли бы иметь

 #define MAX_FOOS 10
 int foos[MAX_FOOS];

В С++ мы предпочли бы писать

 const int max_foos = 10;
 int foos[max_foos];

Для этого работать max_foos необходимо использовать в постоянном выражении. Он также должен иметь внутреннюю связь, поэтому определение может отображаться в заголовке, не вызывая множественных ошибок определения, и что более важно, чтобы упростить компилятору не выделять какое-либо хранилище для max_foos.

Когда комитет C принял const из С++, они не приняли антипатию к макросам, поэтому им не нужны эти семантики.