В чем разница между квалификатором const в C и квалификатором const в C ++?

9

Я нашел комментарий пользователя R .. :

C и C ++ - это не один и тот же язык. В частности, C не constимеет ничего общего с C ++ const.

Я знаю, что одно отличие между constклассификатором в C и constклассификатором в C ++ заключается в его связи по умолчанию.

Объект, объявленный в области пространства имен с constквалификатором в C ++, имеет внутреннюю связь, в то время как в C объект с constквалификатором, объявленным в глобальной области (без staticпредшествующего квалификатора const), имеет внешнюю связь.

Но как еще они отличаются между языками C и C ++? Я думал, что у обоих одинаковые концепции и цели на обоих языках.

Мой вопрос:

  • В чем разница между квалификатором const в C и квалификатором const в C ++?

Ответы на Как отличается "const" в C и C ++? не указывайте точное различие между языками C и C ++ в контексте constклассификатора. Только то, что вы не можете или не можете сделать с этим на определенном языке.

RobertS поддерживает Монику Челлио
источник
Так много ответов, просто поиск Google. Один из них: stackoverflow.com/questions/4486442/…
schaiba
1
В Си constне имеет никакого отношения к связи. Вы можете иметь static constв области видимости файла, и это имеет внутреннюю связь,
Лундин
3
Если вы недовольны текущими ответами на этот вопрос - который совпадает с вашим - рассмотрите возможность размещения награды за него.
Sneftel
3
Я согласен, что связанный дубликат - это плохо. Хороший ответ будет перечислять все различия и не так много объяснять, что constделает то же самое на обоих языках.
Лундин
1
Я могу попытаться написать такой ответ, но мне не хватает гуру C ++, чтобы быть уверенным, что я рассмотрел все различия. Наверху: константные переменные в C ++ являются константными выражениями, в отличие от C. C ++ может const квалифицировать функции-члены. Упомянутая связь. Что-нибудь еще?
Лундин

Ответы:

11
  • Наиболее важным отличием является то, что в C ++ constпеременная является константным выражением (даже до введения C ++ 11 constexpr), а constпеременная в C - нет.

    Это означает, что C ++ позволяет вам делать подобные вещи, const size_t n = 1; static int array[n];но C не допускает этого, предположительно по историческим причинам.

  • В C ++ constиграет роль в определении связи. Это отличается между версиями C ++. По данным cppreference.com (выделено мое):

    Любое из следующих имен, объявленных в области имен, имеет внутреннюю связь:


    • энергонезависимые не шаблонные (начиная с C ++ 14) не встроенные (начиная с C ++ 17) неэкспортированные (начиная с C ++ 20) переменные с константой (включая constexpr), которые не объявлены extern и aren ' • ранее заявлено, что оно имеет внешнюю связь;

    Принимая во внимание, что в C constне играет никакой роли в определении связи вообще - имеют значение только спецификаторы области объявления и класса хранения.

  • В C ++ вы можете constквалифицировать функции-члены. Это невозможно в C, так как не имеет синтаксической поддержки функций-членов.

  • C позволяет constобъявлять -качественные переменные без инициализатора. В C мы можем писать const int x;без инициализаторов, но C ++ не позволяет этого. На первый взгляд это может показаться бессмысленной языковой ошибкой в ​​C, но логическое обоснование состоит в том, что компьютеры имеют аппаратные регистры только для чтения со значениями, установленными аппаратными средствами, а не программными. Это означает, что C остается подходящим для аппаратного программирования.

Лундин
источник
Можете ли вы иметь функции-члены в C?
Максим Егорушкин
1
Обратите внимание, что это const size_t n = 1; static int array[n];работает , только если компилятор может видеть определение nи выполнять постоянное распространение. extern const size_t n; static int array[n];не работает
Максим Егорушкин
Хм, я скорее вижу, что такие аппаратные регистры обрабатываются с помощью указателей, например uint32_t const* x = reinterpret_cast<uint32_t const*>(20102012);...
Аконкагуа,
@Aconcagua Это сделало бы такие регистры несовместимыми с остальной частью карты регистров. И как это позволит вам просматривать фактические значения регистра в отладчике? Например, если вы просто хотите просмотреть регистры набора силиконовых масок только для чтения, чтобы быстро увидеть, с какой частью вы закончили. И, очевидно, вам также необходимо volatileопределить указатель.
Лундин
@ Лундин Признался, не обращал внимания на volatile... Отдых зависит. Отладчики, которые у меня были вручную в этих случаях, также легко могут быть устранены *x. С другой стороны, если регистры отображаются в какой-то области памяти, а компилятор не поддерживает непосредственное размещение переменных в определенных местах памяти (я видел оба), иногда получение переменной в определенном месте памяти может быть немного запутанным (необходимость покрыть это в файле карты ...). В конце концов, меня не волнует наличие переменной в нужном месте или указателя, пока я могу получить задание, которое мне поручено;)
Аконкагуа,
0

С cppreference.com :

constКлассификатор используется в объявлении нелокального энергонезависимую нешаблонном (с C ++ 14) , не инлайн (с C ++ 17) переменная , которая не объявлена externдает его внутренней связи. Это отличается от C, где constпеременные области файла имеют внешнюю связь.

Помимо этого, constимеет одинаковую семантику в C и C ++, а заголовки C constчасто скомпилированы как условные заголовки C ++ "extern C".

Максим Егорушкин
источник
1
Это плохая цитата, упрощение. static const x;в области видимости файла в C есть внутренняя связь. Связывание переменной C определяется областью, в которой она объявлена, а также наличием / отсутствием спецификаторов класса хранения. constи другие классификаторы типов не играют в этом никакой роли.
Лундин
@Lundin Как это отличается от того, что говорится в цитате?
Максим Егорушкин
1
Пример, который я только что привел, доказывает, что цитата неверна. Согласно цитате, static const x;у области видимости файла в C есть внешняя связь.
Лундин
@Lundin Цитата говорит, что int const x = 1в C есть внешняя связь . Следовательно, вам нужно staticизменить связь на внутреннюю. Цитата довольно понятна для меня, в отличие от ваших комментариев.
Максим Егорушкин
1
Это действительно не говорит об этом вообще. Прочитайте цитату. Msgstr "где переменные области видимости файла const имеют внешнюю связь".
Лундин