Constexpr-Zeiger-Wert
Ich versuche zu erklären, constexpr-Zeiger initialisiert, um einen Konstanten integer-Wert, aber das Geräusch ist Folierung alle meine versuche:
Versuch 1:
constexpr int* x = reinterpret_cast<int*>(0xFF);
test.cpp:1:20: note: reinterpret_cast is not allowed in a constant expression
Versuch 2:
constexpr int* x = (int*)0xFF;
test.cpp:1:20: note: cast which performs the conversions of a reinterpret_cast is not allowed in a constant expression
Versuch 3:
constexpr int* x = (int*)0 + 0xFF;
test.cpp:1:28: note: cannot perform pointer arithmetic on null pointer
Ist, was ich versuche zu tun nicht erlaubt ist design? Wenn ja, warum? Wenn nicht, wie kann ich es tun?
Hinweis: gcc akzeptiert alle diese.
Warum brauchen Sie eine constexpr hier? Nicht constexpr effektiv das gleiche wie const, wenn Sie nicht mit einer Funktion?
Nun, zum Beispiel, wenn es ein statisches Mitglied einer Klasse, und es ist nicht constexpr, ich kann nicht initialisieren-line.
Vielleicht eine statische inline-Memberfunktion wäre besser geeignet als ein Daten-member.
Sie sind nicht erlaubt zu initialisieren int inline? Zeiger sind int-Werte (nicht alles) nach unten, so dass selbst wenn es nicht ganz standard (ich weiß nicht, ich don ' T haben eine Kopie der standard bei mir) Sie sollten in der Lage, die meisten Compiler akzeptieren es.
clang und gcc nicht akzeptieren, in-line-Initialisierung eines non-constexpr-Zeiger. Ich weiß nicht, warum - ich würde gerne wissen, die Grund für die, auch.
Nun, zum Beispiel, wenn es ein statisches Mitglied einer Klasse, und es ist nicht constexpr, ich kann nicht initialisieren-line.
Vielleicht eine statische inline-Memberfunktion wäre besser geeignet als ein Daten-member.
Sie sind nicht erlaubt zu initialisieren int inline? Zeiger sind int-Werte (nicht alles) nach unten, so dass selbst wenn es nicht ganz standard (ich weiß nicht, ich don ' T haben eine Kopie der standard bei mir) Sie sollten in der Lage, die meisten Compiler akzeptieren es.
clang und gcc nicht akzeptieren, in-line-Initialisierung eines non-constexpr-Zeiger. Ich weiß nicht, warum - ich würde gerne wissen, die Grund für die, auch.
InformationsquelleAutor HighCommander4 | 2012-04-29
Du musst angemeldet sein, um einen Kommentar abzugeben.
Luc Danton Notizen, Ihre versuche blockiert werden, die von den Regeln in [expr.const]/2, die sagen, dass die verschiedenen Ausdrücke sind nicht erlaubt in core-Konstante Ausdrücke, darunter:
Den ersten Kugel-Regeln aus deinem ersten Beispiel. Das zweite Beispiel ist ausgeschlossen, die von der ersten Kugel oben, plus die in der Regel aus [expr.cast]/4:
Die zweite Kugel wurde Hinzugefügt von WG21 Kern 1313, und klargestellt, dass die Zeiger-Arithmetik auf einem null-Zeiger ist nicht gestattet, in einem Konstanten Ausdruck. Diese Regeln aus deinem Dritten Beispiel.
Selbst wenn diese Einschränkungen nicht gelten für Kern-Konstanten-Ausdrücke, wäre es immer noch nicht möglich zu initialisieren
constexpr
Zeiger mit einem Wert produziert durch Umwandlung eines integer, da ein constexpr Zeiger-variable muss initialisiert werden, indem ein address constant expression, die von [expr.const]/3, die ausgewertet werden müssen, umEinen integer-cast to pointer-Typ ist keiner von diesen.
g++ tut noch nicht streng diese Regeln durchzusetzen, aber seine letzten releases wurden immer näher zu Ihnen, so sollten wir davon ausgehen, dass es irgendwann vollständig umzusetzen.
Wenn Ihr Ziel ist es, eine variable zu deklarieren, für die statische Initialisierung durchgeführt wird, können Sie einfach fallen die
constexpr
- sowohl clang und g++ emittieren, eine statische Initialisierer für diesen Ausdruck. Wenn Sie brauchen, dieser Ausdruck Teil ein konstanter Ausdruck aus irgendeinem Grund, haben Sie zwei Möglichkeiten:__builtin_constant_p((int*)0xFF) ? (int*)0xFF : (int*)0xFF
. Diese genaue form des Ausdrucks (mit__builtin_constant_p
auf der Links-hand-Seite eine bedingte operator) deaktiviert strengen konstanter Ausdruck Prüfung in den Armen der bedingte operator, und ist eine wenig bekannte, aber dokumentiert, nicht tragbare GNU-Erweiterung unterstützt sowohl gcc und clang.InformationsquelleAutor Richard Smith
Der Grund ist das man durch die (für einmal, sehr hilfreiche) Fehlermeldung:
reinterpret_cast
ist nicht erlaubt in einem Konstanten Ausdruck. Es ist aufgeführt als eines der expliziten Ausnahme in 5.19 (Absatz 2).Änderung der
reinterpret_cast
in ein C-style cast noch endet mit dem semantischen äquivalent einesreinterpret_cast
, so dass nicht hilft (und wieder die Nachricht ist sehr explizit).Wenn Sie hatte eine Weg, um einen Zeiger mit dem Wert
0
könnte man ja verwendenp + 0xff
aber ich kann nicht denken, ein Weg, um eine solche Zeiger mit einem Konstanten Ausdruck. Sie konnte sich auf die null-Zeiger-Wert (0
in einen Zeiger-Kontext, wie Sie getan haben, odernullptr
) mit einem Wert von0
auf Ihre Umsetzung aber als Sie gesehen haben, sich Ihre Umsetzung weigert sich, das zu tun. Ich denke, es ist erlaubt das zu tun. (E. g. Implementierungen dürfen-bail-out-für die meisten Konstante Ausdrücke.)0xff/sizeof(*x)
, fügt er hinzu.InformationsquelleAutor Luc Danton