Корректность 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 ответа:
в дополнение к различиям, которые вы цитируете, и различиям в библиотеке, которые Стив Джессоп упоминает,
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++ сделал дальнейшее анализ, понял, что проблема присутствовала только тогда, когда aconst
уровень сопровождался не -const
уровень, и отработал необходимое формулировка. (См. §4.4/4 в стандарте.)
В C
const
объявления не производят константных выражений, т. е. В C вы не можете использовать aconst 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++ , они не приняли антипатию к макросам, поэтому им не нужна была эта семантика.