Const правильность в C против C ++ - PullRequest
57 голосов
/ 18 января 2012

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

Мои вопросы:

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

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

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

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

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

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

Ответы [ 3 ]

24 голосов
/ 18 января 2012

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

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 кроме констант верхнего уровня. (Т. Е. &p1 может быть присваивается char ** или char **const, но не char const** ни char const* const*.) Комитет C ++ сделал дальнейшее анализ, понял, что проблема присутствовала только тогда, когда const за уровнем следовал не const уровень, и вырабатывался необходимый формулировка. (См. §4.4 / 4 в стандарте.)

10 голосов
/ 18 января 2012

В C const объявления не производят константных выражений, т.е. в C вы не можете использовать const int объект в метке регистра, в качестве ширины битового поля или в качестве размера массива в объявлении массива не-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.

5 голосов
/ 19 января 2012

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

В 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 ++, они не применили антипатию к макросам, поэтому им не понадобилась эта семантика.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...