Jaka jest różnica między kwalifikatorem const w C a kwalifikatorem const w C ++?

9

Znalazłem komentarz użytkownika R .. :

C i C ++ nie są tym samym językiem. W szczególności C constnie ma nic wspólnego z C ++ const.

Wiem, że jedną różnicą między constkwalifikatorem w C i constkwalifikatorem w C ++ jest jego domyślne połączenie.

Obiekt zadeklarowany w zakresie przestrzeni nazw z constkwalifikatorem w C ++ ma wewnętrzne powiązanie, podczas gdy w C obiekt z constkwalifikatorem zadeklarowanym w zakresie globalnym (bez wcześniejszego statickwalifikatora const) ma zewnętrzne powiązanie.

Ale jak inaczej różnią się one między językami C i C ++? Myślałem, że oba mają taką samą koncepcję i cel w obu językach.

Moje pytanie:

  • Jaka jest różnica między kwalifikatorem const w C a kwalifikatorem const w C ++?

Odpowiedzi na pytanie: Czym różni się „const” w C i C ++? nie wskazuj dokładnej różnicy między językami C i C ++ w kontekście constkwalifikatora. Tylko to, czego nie możesz zrobić lub możesz zrobić w określonym języku.

RobertS obsługuje Monikę Cellio
źródło
Tak wiele odpowiedzi dzieli tylko wyszukiwarka Google. Jeden z nich: stackoverflow.com/questions/4486442/…
schaiba
1
W C constnie ma nic wspólnego z łączeniem. Możesz mieć static constzakres pliku i ma wewnętrzne powiązanie,
Lundin
3
Jeśli nie jesteś zadowolony z bieżących odpowiedzi na to pytanie - które jest takie samo jak twoje - rozważ umieszczenie nagrody za to.
Sneftel
3
Zgadzam się, że powiązany duplikat jest zły. Dobra odpowiedź zawierałaby wszystkie różnice i nie tyle wyjaśniałaby to constsamo w obu językach.
Lundin
1
Mogę spróbować napisać taką odpowiedź, ale nie jestem wystarczająco guru C ++, aby mieć pewność, że uwzględniono wszystkie różnice. Na szczycie mojej głowy: zmienne const w C ++ są wyrażeniami stałymi, w przeciwieństwie do C. C ++ może const kwalifikować funkcje składowe. Wspomniane połączenie. Coś jeszcze?
Lundin

Odpowiedzi:

11
  • Najważniejszą różnicą jest to, że w C ++ constzmienna jest stałym wyrażeniem (nawet przed wprowadzeniem C ++ 11 constexpr), ale constzmienna w C nie jest.

    Oznacza to, że C ++ pozwala robić takie rzeczy, const size_t n = 1; static int array[n];ale C na to nie pozwala, prawdopodobnie z powodów historycznych.

  • W C ++ constodgrywa rolę w określaniu powiązania. Różni się to między wersjami C ++. Według cppreference.com (moje podkreślenie):

    Każda z następujących nazw zadeklarowanych w zakresie przestrzeni nazw ma powiązanie wewnętrzne:


    • nieulotne nie-szablonowe (od C ++ 14) nie wbudowane (od C ++ 17) nieeksportowane (od C ++ 20) zmienne kwalifikowane przez const (w tym constexpr), które nie są zadeklarowane jako zewnętrzne i nie są t wcześniej zadeklarowany jako zewnętrzny link;

    Podczas gdy w C constnie odgrywa żadnej roli w określaniu powiązania - znaczenie mają jedynie zakres deklaracji i specyfikatory klasy pamięci.

  • W C ++ możesz constzakwalifikować funkcje składowe. Nie jest to możliwe w C, ponieważ nie ma obsługi składni dla funkcji składowych.

  • C umożliwia constdeklarowanie zmiennych kwalifikowanych bez inicjatora. W C możemy pisać const int x;bez inicjatorów, ale C ++ na to nie pozwala. Na pierwszy rzut oka może to wydawać się bezsensownym błędem językowym w C, ale uzasadnieniem jest to, że komputery mają rejestry sprzętowe tylko do odczytu z wartościami ustawionymi przez sprzęt, a nie oprogramowanie. Oznacza to, że C nadal nadaje się do programowania sprzętowego.

Lundin
źródło
Czy możesz mieć funkcje członka w C?
Maxim Egorushkin
1
Zauważ, że const size_t n = 1; static int array[n];działa tylko wtedy, gdy kompilator widzi definicję ni wykonuje stałą propagację. extern const size_t n; static int array[n];nie działa
Maxim Egorushkin
Hm, raczej widzę, jak takie rejestry sprzętowe są adresowane za pomocą wskaźników, takich jak uint32_t const* x = reinterpret_cast<uint32_t const*>(20102012);...
Aconcagua,
@Aconcagua To spowodowałoby, że takie rejestry byłyby niezgodne z resztą mapy rejestrów. A w jaki sposób umożliwiłoby to przeglądanie rzeczywistych wartości rejestrów w debuggerze? Na przykład, jeśli chcesz tylko wyświetlić rejestry zestawu maski silikonowej tylko do odczytu, aby szybko zobaczyć, z jaką częścią się skończyłeś. Oczywiście musisz także volatilezakwalifikować wskaźnik.
Lundin
@Lundin Przyznał, nie zwracał uwagi na volatile... Reszta zależy. Debugery, które miałem ręcznie w tych przypadkach, również mogły łatwo rozwiązać *x. Z drugiej strony, jeśli rejestry są odwzorowane na jakiś obszar pamięci, a kompilator nie obsługuje bezpośredniego umieszczania zmiennych w określonych lokalizacjach pamięci (widziałem oba), uzyskanie zmiennej w określonej lokalizacji pamięci może czasami być nieco nieporządne (konieczność zakrycia tego w pliku mapy ...). Ostatecznie nie dbam o to, aby zmienna znajdowała się we właściwym miejscu lub wskaźniku, o ile mogę wykonać zadanie, do którego mnie przydzielono;)
Aconcagua,
0

Od cppreference.com :

constKwalifikator używany w deklaracji nielokalnego nieulotnej braku szablonu (od C ++ 14) non-inline (od C ++ 17) zmienna, która nie została zadeklarowana externdaje jej wewnętrznego powiązania. Różni się to od C, gdzie constzmienne zakresu plików mają powiązanie zewnętrzne.

Poza tym constma taką samą semantykę w nagłówkach C i C ++, a nagłówki C constsą często kompilowane jako nagłówki C ++ z warunkiem "extern C".

Maxim Egorushkin
źródło
1
To zły cytat, nadmierne uproszczenie. static const x;w zakresie plików w C ma wewnętrzne powiązanie. Powiązanie zmiennej C zależy od zakresu, w którym jest deklarowana, a także od obecności / braku specyfikatorów klasy pamięci. consta inne kwalifikatory typu wcale nie biorą w tym udziału.
Lundin
@Lundin Czym to się różni od tego, co mówi cytat?
Maxim Egorushkin
1
Podany przeze mnie przykład dowodzi, że cytat jest błędny. Zgodnie z cytatem static const x;w zakresie plików w C znajduje się zewnętrzny link.
Lundin
@Lundin Cytat mówi, że int const x = 1w C ma powiązanie zewnętrzne . Dlatego należy staticzmienić powiązanie na wewnętrzne. Cytat jest dla mnie dość jasny, w przeciwieństwie do twoich komentarzy.
Maxim Egorushkin
1
Naprawdę wcale tak nie mówi. Przeczytaj cytat. „... C gdzie zmienne zakresu pliku const mają zewnętrzne powiązanie”.
Lundin