Ist die Adressierung einer lokalen Variablen in C ++ 11 ein konstanter Ausdruck?

Das folgende C ++ 11 Programm:

int x = 42;

void f()
{
        int y = 43;

        static_assert(&x < &y, "foo");
}

int main()
{
        f();
}

Kompiliert nicht mit gcc 4.7, da es sich beschwert:

error: ‘&y’ is not a constant expression

Dies würde meiner Intuition entsprechen. Die Adresse vony ändert sich möglicherweise mit jedem Aufruf vonfDies kann natürlich nicht während der Übersetzung berechnet werden.

Keiner der Aufzählungspunkte in 5.19 [expr.const] scheint jedoch zu verhindern, dass es sich um einen konstanten Ausdruck handelt.

Die einzigen zwei Anwärter, die ich sehe, sind:

eine lvalue-to-rvalue-Konvertierung ...

Aber wenn ich mich nicht irre (?), enthält das Programm keine Konvertierungen von lWert zu rWert.

Und

einid-expression das bezieht sich auf eine Variable [snip] es sei denn:

Es wird mit einem konstanten Ausdruck initialisiert

welchey is - wird mit dem konstanten Ausdruck initialisiert43.

Handelt es sich also um einen Fehler in der Norm oder fehle ich etwas?

Aktualisieren:

Es ist verdammt verwirrend, aber ich glaube, ich bin oben drauf, also lass mich ein Beispiel zeigen, das zeigen wird, was los ist:

int x = 42;

void f()
{
        int y = 43;

        // address constant expressions:    
        constexpr int* px = &x; // OK
        constexpr int* py = &y; // ERROR: pointer context for local variable

        // boolean constant expressions:
        constexpr bool bx = &x; // OK
        constexpr bool by = &y; // OK

        // comparison constant expressions:
        constexpr bool eq = (&x == &y); // OK
        constexpr bool lt = (&x < &y); // ERROR: undefined behaviour disqualifies 
                                                 a constant expression
}

int main()
{
        f();
}

Unterscheiden Sie zunächst zwischen einem konstanten Kernausdruck (5.19p2) und einem konstanten Ausdruck (5.19p4). Insbesondere Unterausdrücke eines konstanten Ausdrucks müssen nur konstante Kernausdrücke sein, keine konstanten Ausdrücke. Das heißt, ein konstanter Ausdruck zu sein, ist eine Eigenschaft des vollständigen Ausdrucks, nicht der Unterausdrücke. Außerdem muss der Kontext betrachtet werden, in dem der vollständige Ausdruck verwendet wird.

Wie sich herausstellt, ist der gcc-Fehler irreführend. zuerst&y kann in manchen Kontexten ein konstanter Ausdruck sein. Zweitens der Grund&x < &y ist kein konstanter Ausdruck, weil nicht verwandte Zeiger verglichen werden, nicht der Unterausdruck&y.

Antworten auf die Frage(6)

Ihre Antwort auf die Frage