3 Stimmen

Warum kann ich eine Header-Datei in mehreren cpp-Dateien einfügen, die const int enthält, ohne einen Compilerfehler zu haben?

Angenommen, ich habe die Dateien a.cpp, b.cpp und die Datei c.h. Beide cpp-Dateien enthalten die c.h-Datei. Die Header-Datei enthält eine Reihe von const int-Definitionen, und wenn ich sie kompiliere, erhalte ich keine Fehler und dennoch kann ich diese const-Zahlen verwenden, als ob sie globale Variablen wären. Die Frage ist also, warum erhalte ich keine Kompilierungsfehler, wenn ich mehrere const-Definitionen habe und diese const ints eine globale Reichtweite haben?

5voto

John Calsbeek Punkte 35029

Dies liegt daran, dass eine const-Deklaration im Namespace-Bereich eine interne Verknüpfung impliziert. Ein Objekt mit interner Verknüpfung ist nur innerhalb der Übersetzungseinheit verfügbar, in der es definiert ist. Also ist das eine const-Objekt, das Sie in c.h haben, tatsächlich zwei verschiedene Objekte, eines intern in a.cpp und eines intern in b.cpp.

Mit anderen Worten,

const int x = ...;

ist äquivalent zu

static const int x = ...;

während

int x;

ähnlich ist wie

extern int x;

weil nicht-const-Deklarationen im Namespace-Bereich eine externe Verknüpfung implizieren. (In diesem letzten Fall sind sie tatsächlich nicht äquivalent. extern, ebenso wie die explizite Spezifikation der externen Verknüpfung, erzeugt eine Deklaration und keine Definition eines Objekts.)

Beachten Sie, dass dies spezifisch für C++ ist. In C ändert const nicht die implizierte Verknüpfung. Der Grund hierfür ist, dass das C++-Komitee wollte, dass Sie schreiben können

const int x = 5;

in einem Header. In C würde dieser Header, der aus mehreren Dateien eingebunden ist, Linkerfehler verursachen, da Sie dasselbe Objekt mehrmals definieren würden.

2voto

Andrew Tomazos Punkte 62162

Aus dem aktuellen C++-Standard...

7.1.1 Spezifizierer für Speicherklasse

7) Ein in einem Namensraumumfang deklarierter Name ohne Speicherklasse-Spezifizierer hat eine externe Verknüpfung, es sei denn, er hat aufgrund einer früheren Deklaration eine interne Verknüpfung und sofern er nicht als const deklariert ist. Als const deklarierte Objekte ohne explizite Deklaration als extern haben eine interne Verknüpfung.

3.5 Programm und Verknüpfung

2) Wenn ein Name intern verknüpft ist, kann auf die von ihm bezeichnete Entität durch Namen aus anderen Bereichen der gleichen Übersetzungseinheit verwiesen werden.

Der Präprozessor führt dazu, dass in Headern definierte Dinge in der aktuellen Übersetzungseinheit eingeschlossen werden.

0voto

iehrlich Punkte 3562

Wenn Sie dies tun, erstellen Sie für jede Konstante im Header eine separate const Variable pro Objektdatei. Es ist kein Problem, da sie const sind.

0voto

Seva Alekseyev Punkte 57252

Echter Grund: weil #define böse ist und sterben muss.

Einige Verwendungen von #define können durch Inline-Funktionen ersetzt werden. Einige - durch const-Variablendeklarationen. Da #define tendenziell in Header-Dateien vorhanden ist, funktioniert es besser, diese durch consts am Ort zu ersetzen. Daher die Regel "Konstanten sind standardmäßig statisch".

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X