Корректность Const в C vs C++


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

мои вопросы:

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

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

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

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

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

что я упустил?

3 52

3 ответа:

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

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

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

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

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

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

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

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

Они не будут работать в c.

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

В C мы могли бы

 #define MAX_FOOS 10
 int foos[MAX_FOOS];

В C++ мы бы предпочли иметь возможность писать

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

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

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