Falsche Freunde? Schlüsselwort "statisch" in C im Vergleich zu C ++, C # und Java

8

Für mich sind die Verwendung des Schlüsselworts staticin C und Sprachen wie C # und Java "falsche Freunde" wie "werden" auf Englisch und "bekommen" auf Deutsch (= "bekommen" auf Englisch), weil sie verschiedene Dinge bedeuten.

In C staticbedeutet, dass auf die Funktion oder Variable nur über Funktionen in derselben Quelldatei zugegriffen werden kann, vergleichbar mit privateFunktionen und Elementen in C ++, Java und C #.

In C ++ bedeutet Java und C # static, dass die Methoden keine Mitglieder einer Klasseninstanz sind, sondern effektiv mehr oder weniger C-Funktionen plus Namespace ähneln.

IMHO sind diese beiden Konzepte sehr unterschiedlich. Warum haben die Designer von C ++ und später Java und C # das staticSchlüsselwort für dieses Verhalten ausgewählt? Gibt es eine logische Verbindung, die ich vermisse?

BEARBEITEN Ich weiß, dass staticin C die Barrierefreiheit nicht ähnlich wie privatein C ++ geregelt wird, sondern auf diese Weise verwendet werden kann, siehe https://stackoverflow.com/a/1479639/124983

Residuum
quelle

Antworten:

9

Ich habe ein Buch über das Design von C ++ von Bjarne Stroustrup (dem Erfinder von C ++). Ich habe es hier nicht richtig, daher kann ich das genaue Zitat momentan nicht nachschlagen, aber darin gibt er zu, dass er beim Hinzufügen staticzu C ++ nicht vollständig verstanden hat, was es in C bedeutete. Deshalb ist es in C ++ so hat eine andere Bedeutung als in C.

Java und C # haben die Bedeutung von C ++ geerbt.

Jesper
quelle
Erstellt hier ein Konto, um diese Antwort zu verbessern! Dies sind erstaunliche Informationen, die ich in meinem Leben als Softwareentwickler niemals missen möchte!
Maverick283
@ Maverick283 Es ist dieses Buch: Das Design und die Entwicklung von C ++
Jesper
14

Insbesondere hat C ++ beide Verwendungszwecke static, und ich denke, irgendwo gibt es einen dritten.

Im Allgemeinen denke ich, dass die C-Verwendung von staticüberhaupt keiner englischen Verwendung des Wortes entspricht, während ich denke, dass staticbeispielsweise als staticMitgliedsvariable viel mehr Sinn macht.

Denken Sie daran, dass Sie als Sprachdesigner einen fairen Anreiz haben, weniger Schlüsselwörter in die Sprache einzuführen und weniger Code zu verbieten - insbesondere, wenn Sie versuchen, mit C quellkompatibel zu sein, wie in C ++, und das staticSchlüsselwort bereits vorhanden ist Sie konnten keine C-Programme brechen, die versuchten, als C ++ zu kompilieren, indem sie es wiederverwendeten.

Edit: Ich wusste, dass es einen dritten gab. C hat staticVariablen auf Funktionsebene . Das staticMitglied ist nur eine Version dieser Funktionalität. Daher stammen beide Verwendungen staticvon C.

DeadMG
quelle
3
c hat zwei statische Verwendungen (Verknüpfung und Lebensdauer), c ++ hat sowohl diese als auch die Klasse eins
jk.
1
@jk: Die Klassenversion ist dasselbe wie die Funktionsebene static, sie ist nur auf eine Klasse anstatt auf eine Funktion beschränkt.
DeadMG
1
@jk. Viele denken an staticdrei Verwendungszwecke in C (Funktionsumfangsvariable, Kompilierungseinheitsbereich für Variablen, Kompilierungseinheitsbereich für Funktionen). In diesen drei Fällen (Verknüpfung und Lebensdauer) macht es wirklich die gleichen Dinge. Ich teile Ihre Meinung dazu. Die Ansicht von drei statischen Verwendungen in C ist leider häufiger. Es hilft den Menschen zu verstehen, wie man es benutzt, aber nicht, wie es wirklich funktioniert.
Gauthier
Sie vergessen die neue Verwendung von statischem C99: stackoverflow.com/questions/3430315/…
Austin
8

Hat in C ++ staticdie folgenden vier Verwendungszwecke:

  • Globale Funktion (Dateiebene) und Variablendeklarationen : Mit static geben Sie die interne Verknüpfung an . Das bedeutet, dass das Symbol nur in dieser einen Kompilierungseinheit verwendet wird (.cpp / cc / welche Datei auch immer, kein Header). Dies ist, was Sie als "privat" bezeichnen.

  • Lokale Variablen : Die statische Speicherdauer gibt an, dass die Variable ihren Wert zwischen Funktionsaufrufen beibehalten soll.

  • Datenelemente : Statische Datenelemente werden von den Instanzen der Klasse gemeinsam genutzt (dh es gibt nur eine Kopie des Mitglieds). Dies ist vergleichbar mit C # und Java Static.

  • Elementfunktionen : Statische Elementfunktionen sind Elementfunktionen ohne impliziten thisZeiger. Sie können ohne Instanz aufgerufen werden. Dies ähnelt auch C # oder Java.

Wie Sie sehen können, haben sie zwei der oben genannten Bedeutungen fallen gelassen. Für das Scoping ist es durchaus verständlich, warum: Sowohl C # als auch Java (und sogar C ++) sind dazu auf Namespaces angewiesen. C ++ verfügt wahrscheinlich über die interne Verknüpfungsfunktion, um die Abwärtskompatibilität zu gewährleisten. Das Verzichten auf statische lokale Variablen ist wahrscheinlich zweifach: Ausnahmsweise kann es schwierig sein, die Konsequenzen vollständig zu verstehen, und diese Sprachen zielen auf Einfachheit ab. Zweitens haben sowohl Java als auch C # einen Garbage Collector, der (wie ich mir vorstellen kann) Schwierigkeiten bei der Implementierung eines solchen Verhaltens verursacht.

Tamás Szelei
quelle
"C ++ verfügt wahrscheinlich über die interne Verknüpfungsfunktion aus Gründen der Abwärtskompatibilität." - Man könnte hinzufügen (IIRC), dass der C ++ - Standard diese Verwendung von static(bevorzugt anonyme Namespaces) zuerst ablehnte und dann in seiner aktuellen Inkarnation C ++ 11 die Verwendung von staticdies ablehnte . (alle IIRC)
Martin Ba
"Ja wirklich?" Ich bin mir ziemlich sicher, dass Compiler diese Ablehnung damals nicht beachteten, da sie mit mindestens zwei Mainstream-Versionen (gcc und MSVC) funktionierte.
Tamás Szelei
Soweit ich weiß, hat es kein Compiler rausgeworfen. Trotzdem denke ich, dass der Standard '98 / '03 ihn oder so etwas veraltet hat. Was ich eigentlich mit meinem Kommentar sagen wollte, war, dass die interne Verknüpfung eine Funktion ist, die anscheinend auch in C ++ als nützlich angesehen wird, sodass sie nicht nur der Abwärtskompatibilität dient.
Martin Ba
Die "c ++ - y" Methode, dasselbe zu tun, besteht darin, in einem anonymen Namespace zu deklarieren.
Tamás Szelei
"ist in einem anonymen Namespace zu deklarieren" - außer dass es technisch nicht dasselbe ist. (Ich entschuldige mich dafür, dass ich nicht mehr Referenzen habe, aber mir fehlt die Zeit, um nachzuschlagen. (Ich denke, es wurde in der comp.lang.c ++. Moderierten NG erwähnt, und vielleicht kann man einige Referenzen in den Standardpapieren finden von WG21 ...)
Martin Ba
3

C ++ hat es von C übernommen, da C ++ vorhandene Schlüsselwörter gerne wiederverwendet, anstatt neue einzuführen, um das Brechen vorhandenen Codes zu minimieren.

Java und C # haben es dann aus C ++ übernommen.

Martin Ba
quelle
3

C staticregelt nicht die Zugänglichkeit und ist nicht analog zu privateder von Ihnen vorgeschlagenen Art und Weise.

Im Dateibereich regelt es die Verfügbarkeit des Namens (Linkersymbol), nicht der Sache - Sie können einen Zeiger auf eine staticFunktion oder eine globale Funktion von der Übersetzungseinheit übergeben, in der der Code in einer anderen Datei definiert ist, und er funktioniert einwandfrei.

Die C ++ - Methode (wie DeadMG sagt, ist die C-Methode auch noch verfügbar) besteht darin, einen anonymen Namespace zu verwenden.

Im Funktionsumfang ersetzt es im Wesentlichen die lokale Variable durch eine globale Variable, auf die nur innerhalb dieser Funktion zugegriffen werden kann (wieder mit Namen!) - dies ist in C ++ identisch (es gibt also keine C ++ y- Methode). .

Warum C ++ das staticQualifikationsmerkmal für Klassenmitglieder verwendet hat; Es ist wahrscheinlich richtig zu sagen, dass dies dazu dient, die Anzahl der neu eingeführten Schlüsselwörter zu minimieren. (Beachten Sie die kürzlich erfolgte Wiederverwendung von Auto zum Vergleich).

Das statische Aufrufen von Daten pro Klasse (so implizit sind Daten pro Instanz dynamisch ) erscheint mir ziemlich intuitiv, aber da ich mich nicht an den Prozess der Bildung dieser Intuition erinnere, kann ich nicht objektiv kommentieren, ob es beim Start sinnvoll war aus.

Nutzlos
quelle