Dlaczego const implikuje wewnętrzne powiązanie w C ++, a nie w C?

83

Zobacz temat. Co oni sobie myśleli?

AKTUALIZACJA: zmieniono z „statycznego” na „wewnętrzne powiązanie”, aby uniknąć nieporozumień.

Aby podać przykład ... Umieszczenie w pliku:

const int var_a = 1;
int var_b = 1;

... i kompilowanie g++ -c test.cpptylko z eksportami var_b.

Johan Kotlinski
źródło

Odpowiedzi:

113

Myślę, że masz na myśli

Dlaczego const implikuje wewnętrzne powiązanie w C ++

Prawdą jest, że jeśli zadeklarujesz obiekt const w zakresie przestrzeni nazw, to ma on wewnętrzne połączenie.

Dodatek C ( C ++ 11, C.1.2 ) zawiera uzasadnienie

Zmiana: nazwa zakresu pliku, która jest jawnie zadeklarowana jako const, a nie jawnie zadeklarowana jako extern, ma wewnętrzne połączenie, podczas gdy w C miałaby połączenie zewnętrzne

Uzasadnienie: Ponieważ obiekty const mogą być używane jako wartości czasu kompilacji w C ++, ta funkcja zachęca programistów do podania jawnych wartości inicjalizujących dla każdej stałej. Ta funkcja umożliwia użytkownikowi umieszczanie obiektów const w plikach nagłówkowych, które są zawarte w wielu jednostkach kompilacji.

Johannes Schaub - litb
źródło
Wygląda na to, że obiekty globalne inne niż const mogą być również inicjalizowane, ale dlaczego standard nie zapewnia wewnętrznego połączenia?
Yong Li
13

Jak powiedział litb, constobiekty mają wewnętrzne powiązania w C ++. Dzieje się tak, ponieważ są przeznaczone do użycia w następujący sposób:

// a.cpp
const int BUFSIZE = 100;
char abuf[BUFSIZE];

// b.cpp
const int BUFSIZE = 256
int bbuf[BUFSIZE];
RobertS wspiera Monikę Cellio
źródło
6

Const i static to pojęcia ortogonalne zarówno w C, jak i C ++.

Plik constKluczowe informuje kompilator, aby uniemożliwić zmienną pojawianiu jako lwartości jakiegokolwiek wyrazu - w istocie czyni go tylko do odczytu.

W języku C staticsłowo kluczowe ma kilka zastosowań w zależności od tego, do czego jest stosowane. Po zastosowaniu do zmiennej funkcji wskazuje, że zmienna nie jest przechowywana w lokalnym zakresie funkcji, ale jest dostępna przez jej wywołania. Po zastosowaniu do zmiennej lub funkcji globalnej staje się dostępna tylko dla określonego pliku - innymi słowy, jest dostępna tylko w jednostce kompilacji (o ile nie została zadeklarowana extern).

W C ++ staticsłowo kluczowe może być używane w definicji klasy, aby zmienna lub funkcje były wspólne dla wszystkich instancji klasy, zamiast być lokalną dla każdej instancji. Ponadto statyczna funkcja klasy w C ++ ma dostęp tylko do zmiennych statycznych tej klasy (lub klas, do których ma dostęp). Teraz w C ++ constdaje członkom wewnętrzne powiązanie z jednostką kompilacji, chyba że są wyraźnie zadeklarowane extern- może to być to, do czego się odnosisz. Umożliwia to współdzielenie stałych czasu kompilacji w całej jednostce za pomocą plików nagłówkowych. Pamiętaj jednak, że składowe nie są tak naprawdę statyczne - raczej stała jest kompilowana w każdym miejscu, do którego się odwołuje.

L Bushkin
źródło
6

W C i C ++ termin statyczny ma wiele znaczeń (może regulować łączenie i przechowywanie) Będziesz musiał przeczytać D&E Stroustrupa, aby docenić jego uzasadnienie - ale kiedy deklarujesz zmienną jako stałą w zakresie przestrzeni nazw, automatycznie ma ona wewnętrzne powiązanie - podczas gdy w C musisz zadeklarować to jako statyczne, aby wymusić na nim wewnętrzne połączenie.

Oczywiście w C ++ użycie statycznego do kontrolowania powiązań stało się przestarzałe, anonimowe przestrzenie nazw mogą być używane do symulacji wewnętrznego łączenia w C ++.

zmienne const w C ++ miały zastąpić stałe preprocesora - a ponieważ stałe preprocesora są widoczne tylko w plikach, które je definiują, podobnie const automatycznie sprawia, że ​​zmienna jest widoczna tylko w pliku, który ją definiuje.

Faisal Vali
źródło
4

Te pojęcia są ortogonalne i nie należy ich uważać za to samo.

Stałość jest właściwością dostępu: mówi tylko, czy zmienna ma być tylko do odczytu (stała), czy do odczytu i zapisu (nie jest stała).

Statyczność to właściwość związana z czasem życia (i technicznie lokalizacją pamięci): informuje, czy zmienna będzie globalna w zakresie klasy (gdy jest w klasie) lub jednostką tłumaczenia (w przypadku użycia ze zmienną globalną zdefiniowaną w cpp) .

Klaim
źródło
-2

Tak nie jest, a najbardziej oczywistym przykładem jest to, że jeśli masz zmienną składową const (która jest oczywiście inicjowana przez konstruktora), nie jest ona wspólna dla wszystkich obiektów tej klasy, ale dla każdego indywidualna.

class A {
public:
  A(int newx) : x(newx);
private
  int x;
}

litb daje najlepszą odpowiedź powyżej.

Alex Brown
źródło
Czy on nie zawsze? (litb)
RastaJedi
-5

Tak nie jest. Pisząc co następuje:

const int i = 0;

nie czyni istatycznym (w C lub C ++).

Martin Cote
źródło