次の C++11 プログラム:
int x = 42;
void f()
{
int y = 43;
static_assert(&x < &y, "foo");
}
int main()
{
f();
}
次のように、gcc 4.7 ではコンパイルされません。
error: ‘&y’ is not a constant expression
これは私の直感と一致します。のアドレスは のy
呼び出しごとに変わる可能性がf
あるため、もちろん変換中に計算することはできません。
ただし、5.19 [expr.const] の箇条書きのいずれも、定数式であることを排除していないようです。
私が見る唯一の2つの候補は次のとおりです。
左辺値から右辺値への変換...
しかし、私が間違っていない限り (?)、プログラムには左辺値から右辺値への変換はありません。
と
次の
id-expression
場合を除き、変数を参照する [中略]:
- 定数式で初期化されます
つまりy
、定数式で初期化されます43
。
これは標準のエラーですか、それとも何か不足していますか?
アップデート:
それは地獄のように紛らわしいですが、私はそれの上にあると思うので、何が起こっているかを示す例を示しましょう:
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();
}
最初に、コア定数式 (5.19p2) と定数式 (5.19p4) を区別します。具体的には、定数式のサブ式は、定数式ではなく、コア定数式である必要があります。つまり、定数式であることは、サブ式ではなく、完全な式のプロパティです。さらに、完全な式が使用されているコンテキストを調べる必要があります。
そのため、gcc エラーは誤解を招くものであることが判明しました。First&y
は、一部のコンテキストでは定数式である場合があります。第二に、定数式ではない理由&x < &y
は、サブ式ではなく、無関係なポインターの比較によるもの&y
です。