Ich denke, dir fehlt hier etwas.
statische Funktion?
Wenn Sie eine Funktion als statisch deklarieren, wird sie in ihrer Kompilierungseinheit "versteckt".
Ein Name mit Namespace-Bereich (3.3.6) hat eine interne Verknüpfung, wenn es sich um den Namen von handelt
- eine Variable, Funktion oder Funktionsvorlage, die explizit als statisch deklariert ist;
3,5 / 3 - C ++ 14 (n3797)
Wenn ein Name eine interne Verknüpfung hat, kann auf die Entität, die er bezeichnet, durch Namen aus anderen Bereichen in derselben Übersetzungseinheit verwiesen werden.
3,5 / 2 - C ++ 14 (n3797)
Wenn Sie diese statische Funktion in einem Header deklarieren, verfügen alle Kompilierungseinheiten einschließlich dieses Headers über eine eigene Kopie der Funktion.
Die Sache ist, wenn diese Funktion statische Variablen enthält, hat jede Kompilierungseinheit, die diesen Header enthält, auch eine eigene, persönliche Version.
Inline-Funktion?
Wenn Sie es als Inline deklarieren, ist es ein Kandidat für Inlining (dies bedeutet heutzutage in C ++ nicht viel, da der Compiler inline ist oder nicht, wobei manchmal die Tatsache ignoriert wird, dass das Schlüsselwort inline vorhanden ist oder fehlt):
Eine Funktionsdeklaration (8.3.5, 9.3, 11.3) mit einem Inline-Spezifizierer deklariert eine Inline-Funktion. Der Inline-Spezifizierer gibt der Implementierung an, dass die Inline-Substitution des Funktionskörpers am Aufrufpunkt dem üblichen Funktionsaufrufmechanismus vorzuziehen ist. Eine Implementierung ist nicht erforderlich, um diese Inline-Ersetzung am Aufrufpunkt durchzuführen. Selbst wenn diese Inline-Ersetzung weggelassen wird, bleiben die anderen in 7.1.2 definierten Regeln für Inline-Funktionen ein.
7.1.2 / 2 - C ++ 14 (n3797)
In einem Header hat dies einen interessanten Nebeneffekt: Die Inlined-Funktion kann im selben Modul mehrmals definiert werden, und der Linker fügt "sie" einfach zu einem zusammen (wenn sie aus Compiler-Gründen nicht inliniert wurden).
Für statische Variablen, die im Inneren deklariert sind, gibt der Standard ausdrücklich eine und nur eine davon an:
Eine statische lokale Variable in einer externen Inline-Funktion bezieht sich immer auf dasselbe Objekt.
7.1.2 / 4 - C ++ 98 / C ++ 14 (n3797)
(Funktionen sind standardmäßig extern. Wenn Sie Ihre Funktion nicht ausdrücklich als statisch markieren, gilt dies für diese Funktion.)
Dies hat den Vorteil "statisch" (dh es kann in einem Header definiert werden) ohne seine Fehler (es existiert höchstens einmal, wenn es nicht inline ist)
statische lokale Variable?
Statische lokale Variablen haben keine Verknüpfung (sie können außerhalb ihres Gültigkeitsbereichs nicht mit Namen bezeichnet werden), haben jedoch eine statische Speicherdauer (dh sie sind global, aber ihre Konstruktion und Zerstörung unterliegen bestimmten Regeln).
statisch + inline?
Das Mischen von Inline und Static hat dann die von Ihnen beschriebenen Konsequenzen (selbst wenn die Funktion inline ist, ist die darin enthaltene statische Variable nicht vorhanden, und Sie werden mit so vielen statischen Variablen enden, wie Sie über Kompilierungseinheiten verfügen, einschließlich der Definition Ihrer statischen Funktionen ).
Antwort auf die zusätzliche Frage des Autors
Seit ich die Frage geschrieben habe, habe ich sie mit Visual Studio 2008 ausprobiert. Ich habe versucht, alle Optionen zu aktivieren, mit denen VS in Übereinstimmung mit Standards funktioniert, aber es ist möglich, dass ich einige verpasst habe. Dies sind die Ergebnisse:
Wenn die Funktion nur "inline" ist, gibt es nur eine Kopie der statischen Variablen.
Wenn die Funktion "statisch inline" ist, gibt es so viele Kopien wie Übersetzungseinheiten.
Die eigentliche Frage ist nun, ob die Dinge so sein sollen oder ob dies eine Eigenart des Microsoft C ++ - Compilers ist.
Ich nehme an, Sie haben so etwas:
void doSomething()
{
static int value ;
}
Sie müssen sich darüber im Klaren sein, dass die statische Variable innerhalb der Funktion, einfach ausgedrückt, eine globale Variable ist, die für alle außer dem Funktionsumfang verborgen ist, was bedeutet, dass nur die Funktion, in der sie deklariert ist, sie erreichen kann.
Das Inlining der Funktion ändert nichts:
inline void doSomething()
{
static int value ;
}
Es wird nur eine versteckte globale Variable geben. Die Tatsache, dass der Compiler versucht, den Code einzubinden, ändert nichts an der Tatsache, dass es nur eine globale versteckte Variable gibt.
Wenn Ihre Funktion nun als statisch deklariert ist:
static void doSomething()
{
static int value ;
}
Dann ist es für jede Kompilierungseinheit "privat", was bedeutet, dass jede CPP-Datei einschließlich des Headers, in dem die statische Funktion deklariert ist, eine eigene private Kopie der Funktion hat, einschließlich ihrer eigenen privaten Kopie der globalen versteckten Variablen, also so viele Variablen wie Es gibt Kompilierungseinheiten einschließlich des Headers.
Hinzufügen von "Inline" zu einer "statischen" Funktion mit einer "statischen" Variablen im Inneren:
inline static void doSomething()
{
static int value ;
}
hat das gleiche Ergebnis, als dieses "Inline" -Schlüsselwort nicht hinzuzufügen, was die darin enthaltene statische Variable betrifft.
Das Verhalten von VC ++ ist also korrekt, und Sie verwechseln die wahre Bedeutung von "Inline" und "Static".