Яка різниця між класифікатором 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класифікатора. Тільки те, що ти не можеш зробити чи не можеш зробити з певної мови.


Стільки відповідей лише в пошуку Google. Один з них: stackoverflow.com/questions/4486442 / ...
schaiba

1
В C constне має нічого спільного із зв'язком. Ви можете мати static constрозмір файлу, і він має внутрішні посилання,
Лундін

3
Якщо ви незадоволені поточними відповідями на це запитання - що таке саме, як і ваше, - подумайте про те, щоб розмістити його за гроші.
Sneftel

3
Я згоден, що пов'язаний дублікат поганий. Хороша відповідь містила б перелік усіх відмінностей і не стільки пояснює, що constробить те саме в обох мовах.
Лундін

1
Я можу спробувати написати таку відповідь, але мені недостатньо гуру С ++, щоб бути впевненим, що я покрив усі відмінності. Нагорі голови: змінні const у C ++ є постійними виразами, на відміну від C. C ++ може обмежувати функції члена. Згаданий зв'язок. Ще щось?
Лундін

Відповіді:


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) const-змінні змінні (включаючи constexpr), які не оголошуються зовнішніми і не є ' t раніше оголошено наявність зовнішньої зв'язку;

    Тоді як в 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кваліфікувати вказівник.
Лундін

@Lundin Признався, не звертав уваги на volatile... Відпочинок залежить. Налагоджувачі, які я мав під рукою в цих випадках, також легко могли вирішитись *x. З іншого боку, якщо регістри відображаються в якійсь області пам’яті, а компілятор не підтримує розміщення змінних у певних місцях пам'яті безпосередньо (я бачив і те й інше), отримання змінної у певному місці пам’яті іноді може трохи заплутатися. (маючи прикрити це у файлі карти ...). Зрештою, я не дуже переймаюся тим, що змінна розташована в потрібному місці чи вказівнику, якщо я можу отримати завдання, яке мені призначено;)
Aconcagua,

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
Це насправді зовсім не говорить про це. Прочитайте цитату. "... C, де змінні області файлів const мають зовнішній зв'язок".
Лундін
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.