Следующая программа С++ 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], по-видимому, не позволяет ему быть постоянным выражением.
Единственные два претендента, которых я вижу:
преобразование lvalue-to-rvalue...
но если я ошибаюсь (?), в программе нет преобразований lvalue-rvalue.
и
a
id-expression
, который ссылается на переменную [snip], если только:
- он инициализируется константным выражением
который y
есть - он инициализируется константным выражением 43
.
Итак, это ошибка в стандарте, или я чего-то не хватает?
Update:
Это сбивает с толку, но я думаю, что я на высоте, поэтому позвольте мне показать пример, который будет показывать, что происходит:
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 вводит в заблуждение. Во-первых, &y
может быть постоянным выражением в некоторых контекстах. Во-вторых, причина &x < &y
не является постоянным выражением из-за сравнения несвязанных указателей, а не подвыражения &y
.