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

Я нашел комментарий пользователя 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. Только то, что вы не можете или можете сделать с ним на определенном языке.


person RobertS supports Monica Cellio    schedule 07.02.2020    source источник
comment
Так много ответов, просто поиск в Google. Один из них: stackoverflow.com/questions/4486442/   -  person schaiba    schedule 07.02.2020
comment
@schaiba Нет, ответы на самом деле не указывают на разницу между языками. Только то, как они ведут себя на определенном языке.   -  person RobertS supports Monica Cellio    schedule 07.02.2020
comment
В C const не имеет ничего общего со связью. Вы можете иметь static const в области файла и иметь внутреннюю связь,   -  person Lundin    schedule 07.02.2020
comment
Помимо этого, очевидная разница будет состоять в том, что C++ может сделать функции-члены константными, чтобы заблокировать функцию от изменения значений членов класса. В C этого нет, поскольку в нем нет классов.   -  person Lundin    schedule 07.02.2020
comment
Если вы недовольны текущими ответами на этот вопрос, которые совпадают с вашими, подумайте о том, чтобы опубликовать награду за него.   -  person Sneftel    schedule 07.02.2020
comment
Я согласен, что связанный дубликат плохой. Хороший ответ будет перечислять все различия, а не объяснять, что const делает одинаково на обоих языках.   -  person Lundin    schedule 07.02.2020
comment
Я могу попытаться написать такой ответ, но я недостаточно гуру С++, чтобы быть уверенным, что у меня есть все различия. В верхней части моей головы: константные переменные в C++ являются константными выражениями, в отличие от C++. C++ может определять константные функции-члены. Упомянутая связка. Что-нибудь еще?   -  person Lundin    schedule 07.02.2020
comment
@Lundin - За ваш первый комментарий. - Да, я знаю. Я просто хотел указать, что f.e.const int a = 34; без static по умолчанию имеет внешнюю связь, а static const int a = 34; действительно имеет внутреннюю связь.   -  person RobertS supports Monica Cellio    schedule 07.02.2020
comment
@Lundin Это было бы здорово. Если вы не хотите охватить все, даже хорошая база подойдет. Также вы можете классифицировать ответ, если хотите, тэг-вики-ответ. Кстати, я видел, что у вас 1900 баллов по C++. Не унижайте себя.   -  person RobertS supports Monica Cellio    schedule 07.02.2020


Ответы (2)


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

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

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

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


    • non-volatile non-template (since C++14) non-inline (since C++17) non-exported (since C++20) const-qualified variables (including constexpr) that aren't declared extern and aren't previously declared to have external linkage;

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

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

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

person Lundin    schedule 07.02.2020
comment
Можете ли вы иметь функции-члены в C? - person Maxim Egorushkin; 07.02.2020
comment
Обратите внимание, что const size_t n = 1; static int array[n]; работает только в том случае, если компилятор может видеть определение n и выполнять постоянное распространение. extern const size_t n; static int array[n]; не работает. - person Maxim Egorushkin; 07.02.2020
comment
Хм, я скорее вижу, что к таким аппаратным регистрам обращаются через указатели, такие как uint32_t const* x = reinterpret_cast<uint32_t const*>(20102012);... - person Aconcagua; 07.02.2020
comment
@Aconcagua Это сделало бы такие регистры несовместимыми с остальной частью карты регистров. И как это позволит вам просматривать фактические значения регистров в отладчике? Например, если вы просто хотите просмотреть регистры наборов кремниевых масок только для чтения, чтобы быстро увидеть, какая часть у вас закончилась. И, очевидно, вам также нужно будет volatile квалифицировать указатель. - person Lundin; 07.02.2020
comment
@Lundin Признаюсь, не обратил внимания на volatile... Остальное зависит. Отладчики, которые у меня были под рукой в ​​этих случаях, также могли легко разрешить *x. С другой стороны, если регистры сопоставлены с какой-то областью памяти, а компилятор не поддерживает непосредственное размещение переменных в определенных местах памяти (я видел и то, и другое), получение переменной в определенном месте памяти иногда может стать немного запутанным. (необходимо указать это в файле карты...). В конце концов, меня не очень волнует наличие переменной, расположенной в нужном месте, или указателя, если я могу выполнить поставленную передо мной задачу;) - person Aconcagua; 07.02.2020
comment
@Lundin Я добавил больше частей из исходного источника в цитируемую цитату, чтобы показать контекст, в котором цитата является частью точки / типа для внутренней связи. - person RobertS supports Monica Cellio; 07.02.2020

С сайта cppreference.com:

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

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

person Maxim Egorushkin    schedule 07.02.2020
comment
Плохая цитата, упрощение. static const x; в области файлов в C имеет внутреннюю связь. Связывание переменной C определяется областью, в которой она объявлена, а также наличием/отсутствием спецификаторов класса хранения. const и другие квалификаторы типа вообще не играют роли. - person Lundin; 07.02.2020
comment
@Lundin Чем это отличается от того, что говорит цитата? - person Maxim Egorushkin; 07.02.2020
comment
Пример, который я только что привел, доказывает, что цитата неверна. Согласно цитате, static const x; в области файлов в C имеет внешнюю связь. - person Lundin; 07.02.2020
comment
@Lundin Цитата говорит, что int const x = 1 в C имеет внешнюю связь. Следовательно, вам понадобится static, чтобы изменить связь на внутреннюю. Цитата довольно ясна для меня, в отличие от ваших комментариев. - person Maxim Egorushkin; 07.02.2020
comment
На самом деле это совсем не так. Прочтите цитату. ...C, где константные переменные области видимости файла имеют внешнюю связь. - person Lundin; 07.02.2020
comment
@MaximEgorushkin Lundin означает, что предложение Это отличается от C, где константные переменные области видимости файла имеют внешнюю связь. скорее должно быть Это отличается от C, где константная область действия файла (без статического квалификатора перед const ) переменные имеют внешнюю связь. должны быть на 100% правильными и недвусмысленными. - person RobertS supports Monica Cellio; 07.02.2020
comment
@RobertSsupportsMonicaCellio Оригинальная цитата для меня совершенно однозначна. Просто к вашему сведению: cppreference — это вики, вы можете ее редактировать. - person Maxim Egorushkin; 07.02.2020
comment
Что ж, это вопрос интерпретации. Одни считают переменные const и static const двумя отдельными наборами без пересечения, другие считают, что последний является подмножеством первого. В зависимости от той или иной интерпретации предложение является правильным или неправильным. Неоднозначность? Что ж, пока мы не договорились о том, какое определение применимо, это... - person Aconcagua; 07.02.2020