Okay, statische globale Variable in .h-Datei zu deklarieren?

Lesezeit: 4 Minuten

Batmans Benutzeravatar
Batman

Das Schlüsselwort static beschränkt den Geltungsbereich einer globalen Variablen auf diese Übersetzungseinheit. Wenn ich benutze static int x in einer .h-Datei und fügen Sie diese .h-Datei in jede andere Datei ein, gehören sie nicht alle zu derselben Übersetzungseinheit? Wird x dann nicht überall sichtbar sein? Welche Rolle spielt nun die statische Aufladung?

Gibt es auch eine Verwendung von static const int x ,wobei x eine globale Variable ist? Sind nicht alle konstanten globalen Variablen standardmäßig statisch? Und ist der Geltungsbereich einer konstanten Variablen auf die TU beschränkt, selbst wenn sie in einer for-Schleife in der Datei eingeschlossen ist?

  • Ich habe festgestellt, dass die häufigste Verwendung von Statics in Headern darin besteht, Fehler einzufügen oder das Debuggen zu erschweren.

    – PlasmaHH

    15. August 2012 um 10:21 Uhr


Benutzeravatar von Alexander Chertov
Alexander Tschertow

Wenn du schreibst

static const int x

in einem (n .h Datei dann jede Übersetzungseinheit das #enthalten– ist das .h wird eine eigene private Variable haben x.

Wenn Sie 1 globale Variable für alle sichtbar haben möchten, sollten Sie schreiben

extern const int x;

in dem .h Datei und

const int x = ...;

in einem der .cpp Dateien.

Wenn Sie möchten, dass eine statische Konstante int nur für eine Übersetzungseinheit sichtbar ist, erwähnen Sie sie nicht in der .h Dateien überhaupt.

  • Aber jeder Header hat einen Zaun #ifndef , der nur einmal enthalten sein sollte?

    – Chao

    4. April 2020 um 22:18 Uhr

  • Das ist eine separate Frage (ich habe nie Seed-Header, die mehr als einmal enthalten sein sollten). Auch wenn Sie #ifndef-Zäune haben, müssen Sie immer noch überlegen, ob Sie sie brauchen extern oder nicht.

    – Alexander Tschertow

    6. April 2020 um 11:50 Uhr

Benutzeravatar von Heisenbug
Heisenbug

Wenn ich static int x in einer .h-Datei verwende und diese .h-Datei in jede andere Datei einfüge, gehören sie dann nicht alle zur selben Übersetzungseinheit?

Wenn Sie etwas als statisch deklarieren (nicht innerhalb einer Klasse, da das Schlüsselwort static eine andere Semantik hat), kann diese statische Variable nicht außerhalb ihrer TU gesehen werden. Wenn Sie es also in die Header-Datei einfügen, wird jede TU, die diesen Header enthält, eine andere private Kopie dieser statischen Variablen haben.

Und ist der Geltungsbereich einer konstanten Variablen auf die TU beschränkt, selbst wenn sie in einer for-Schleife in der Datei eingeschlossen ist?

NEIN. Selbst für einen statischen konstanten Wert wird der Geltungsbereich durch seine Deklaration bestimmt. Der Umfang wird also durch Ihre for-Klammern begrenzt.

Sie werden am Ende private Kopien dieser Variablen pro Übersetzung erhalten, was zu einer Aufblähung führt, wenn Sie sie dort ablegen. Es würde auch keinen Sinn machen, überall zufällige Kopien zu haben. nein, es ist nicht in Ordnung.

Sie können a erklären const int in einem namespace Block; das ist okay.

Die beobachtbare Differenz für Variablen, die sind const qualifiziert ist das in der static Version erhalten Sie eine Kopie pro Übersetzungseinheit, sodass Adressvergleiche von zwei solchen Kopien fehlschlagen können.

Wenn Sie nie die Adresse Ihres verwenden const Variable sollte jeder moderne Compiler in der Lage sein, einfach den Wert zu verwenden und die Variable selbst zu optimieren. In einem solchen Fall a static const-qualifizierte Variable ist völlig in Ordnung.

Grundsätzlich ist jede Quelldatei zusammen mit allen enthaltenen Header-Dateien eine einzelne Übersetzungseinheit. Wenn Sie also eine statische Variable in einer Header-Datei haben, ist diese in jeder Quelldatei (Übersetzungseinheit), in der die Header-Datei enthalten ist, eindeutig.

Benutzeravatar von Lundin
Lundin

“statisch global” ergibt keinen Sinn, sie sind gewissermaßen Gegensätze.

Der Begriff „global“ wird oft missbraucht, um eine Variable zu beschreiben, die außerhalb irgendeiner Funktion deklariert wurde Dateibereich. Vielmehr ist eine globale Variable eins mit externe Verknüpfungauf die von jeder Datei im Projekt zugegriffen werden kann – daher global.

Das Gegenteil von externer Verlinkung ist interne Verknüpfungwas bedeutet, dass auf eine Variable nur von der zugegriffen werden kann Übersetzungseinheit wo es deklariert ist. Übersetzungseinheit bedeutet eins .c Datei und alle darin enthaltenen Header (rekursiv).

static ist eine Garantie dafür, dass eine Variable eine interne Verknüpfung erhält. Daher können andere Übersetzungen nicht darauf zugreifen oder sie deklarieren extern darauf verweisende Variablen.

Was passiert, wenn Sie a static Variable in einer Header-Datei ist, dass mehr als eine Übersetzungseinheit eine separate Variable mit diesem Namen erhält. Der Code wird gut kompiliert, obwohl clevere Linker dies bemerken und einen Linker-Fehler ausgeben. Diese Art von Linker-Fehlern sind oft nicht beschreibend und schwer aufzuspüren.

Dies führt uns zu den folgenden Best Practices:

  • Niemals deklarieren irgendein Variablen in einer Header-Datei, da dies oft zu subtilen Bugs und Linker-Fehlern führt.
  • Um solche Fehler zu vermeiden, umgeben Sie immer alle Header-Dateien mit “Header Guards”:

    #ifndef MYHEADER_H 
    #define MYHEADER_H 
      /* contents of header */ 
    #endif
    
  • Alle im Dateibereich deklarierten Variablen sollten deklariert werden static, zum Zwecke der privaten Kapselung und zum Reduzieren von Namespace-Unordnung. Ähnlich, extern sollte vermieden werden, da es zu schlechtem Design und Spaghetti-Programmierung führt.

1433270cookie-checkOkay, statische globale Variable in .h-Datei zu deklarieren?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy