Zitiert N4140 [dcl.constexpr]/9:
A constexpr
specifier used in an object declaration declares the object as const
. Such an object shall have literal type and shall be initialized.
Literal-Typ wird in definiert [basic.types]/10:
A type is a literal type if it is:
(10.1) — void
; or
(10.2) — a scalar type; or
(10.3) — a reference type; or
(10.4) — an array of literal type; or
(10.5) — a class type (Clause 9) that has all of the following properties:
(10.5.1) — it has a trivial destructor,
(10.5.2) — it is an aggregate type (8.5.1) or has at least one constexpr
constructor or constructor template that is not a copy or move constructor, and
(10.5.3) — all of its non-static data members and base classes are of non-volatile literal types.
skalaren Typ ist in Absatz 9:
int
ist arithmetisch, also ist volatile int
ein Skalartyp und daher ein Literaltyp. constexpr volatile int i = 5;
ist also eine wohlgeformte Erklärung.
Interessanterweise ein Ausdruck, der i
kann nicht sein, eine Kern-Konstante-expression da es gilt ein L-Wert-zu-R-Wert Umwandlung in ein glvalue von flüchtigen Typ ([expr.const]/2) auswertet. Folglich sind Ausdrücke, die i
auswerten, weder Integralkonstantenausdrücke noch Konstantenausdrücke. Ich bin mir nicht sicher, ob die constexpr
in dieser Deklaration irgendeinen Effekt hat, außer i
implizit const
zu machen, und (nicken zu @T.C.), dass sein Initialisierer ein konstanter Ausdruck sein muss.
Ich habe dies als GCC bug 65327 gemeldet, wir werden sehen, was die GCC Leute zu sagen haben.
2015-03-16 Update: Bug wurde für GCC festgelegt 5.
Was ist es, Sie versuchen, auszudrücken? Sie sind im Wesentlichen Gegensätze. Eine Konstante wird sich nie ändern, sobald sie gesetzt ist, aber ein Volatile ist fast garantiert, sich zu ändern (möglicherweise sogar von einem anderen Thread). – TheBuzzSaw
'conetexpr' und' const' sind nicht gleich –
@TheBuzzSaw: 'volatile' bedeutet nicht, dass irgendetwas eine Tendenz zur Veränderung hat. es bedeutet nur, dass der Speicherzugriff Nebenwirkungen haben kann, und der Compiler sollte es daher als I/O behandeln. Es kann sehr gut notwendig sein, "flüchtig" auf einem System zu verwenden, selbst wenn der Wert garantiert konstant bleibt. – Mehrdad