Die kurze Antwort lautet: Es ist nicht nur static
nützlich, es wird auch immer erwünscht sein.
Beachten Sie zunächst, dass static
und constexpr
völlig unabhängig voneinander sind. static
definiert die Lebensdauer des Objekts während der Ausführung; constexpr
Gibt an, dass das Objekt während der Kompilierung verfügbar sein soll. Kompilierung und Ausführung sind zeitlich und räumlich unzusammenhängend und nicht zusammenhängend. Sobald das Programm kompiliert ist, constexpr
ist es nicht mehr relevant.
Jede Variable deklariert constexpr
ist implizit const
aber const
und static
sind fast orthogonal ( mit Ausnahme der Interaktion mit static const
ganzen Zahlen.)
Das C++
Objektmodell (§1.9) erfordert, dass alle Objekte außer Bitfeldern mindestens ein Byte Speicher belegen und Adressen haben; Darüber hinaus müssen alle in einem Programm zu einem bestimmten Zeitpunkt beobachtbaren Objekte unterschiedliche Adressen haben (Absatz 6). Dies erfordert nicht ganz, dass der Compiler für jeden Aufruf einer Funktion mit einem lokalen nicht statischen const-Array ein neues Array auf dem Stapel erstellt, da der Compiler in das as-if
Prinzip flüchten könnte, vorausgesetzt, er kann beweisen, dass kein anderes solches Objekt sein kann beobachtete.
Dies wird leider nicht leicht zu beweisen sein, es sei denn, die Funktion ist trivial (z. B. ruft sie keine andere Funktion auf, deren Körper in der Übersetzungseinheit nicht sichtbar ist), da Arrays mehr oder weniger per Definition Adressen sind. In den meisten Fällen muss das nicht statische const(expr)
Array bei jedem Aufruf auf dem Stapel neu erstellt werden, was den Punkt zunichte macht, dass es zur Kompilierungszeit berechnet werden kann.
Andererseits wird ein lokales static const
Objekt von allen Beobachtern gemeinsam genutzt und kann darüber hinaus initialisiert werden, selbst wenn die Funktion, in der es definiert ist, niemals aufgerufen wird. Keiner der oben genannten Punkte trifft also zu, und ein Compiler kann nicht nur eine einzige Instanz davon generieren. Es ist kostenlos, eine einzelne Instanz davon im Nur-Lese-Speicher zu generieren.
Sie sollten es also unbedingt static constexpr
in Ihrem Beispiel verwenden.
Es gibt jedoch einen Fall, in dem Sie nicht verwenden möchten static constexpr
. Sofern ein constexpr
deklariertes Objekt nicht ODR-verwendet oder deklariert ist static
, kann der Compiler es überhaupt nicht einschließen. Das ist ziemlich nützlich, da temporäre constexpr
Arrays zur Kompilierungszeit verwendet werden können, ohne das kompilierte Programm mit unnötigen Bytes zu belasten. In diesem Fall möchten Sie eindeutig nicht verwenden static
, da static
das Objekt wahrscheinlich zur Laufzeit erzwungen wird.
const
von einemconst
Objekt wegwerfen, nur von einem,const X*
das auf ein zeigtX
. Aber darum geht es nicht; Der Punkt ist, dass automatische Objekte keine statischen Adressen haben können. Wie gesagt,constexpr
hört nach Abschluss der Kompilierung auf, aussagekräftig zu sein, sodass nichts wegzuwerfen ist (und möglicherweise gar nichts, da nicht einmal garantiert wird, dass das Objekt zur Laufzeit existiert.)