Код, приведенный ниже, компилируется в GCC, clang и VS2017, а выражение a->i в операторе return заменяется его постоянным значением 1. Правильно ли это сказать, что это верно, поскольку a не является odr-используемым в выражении a->i?.
struct A
{
static const int i = 1;
};
int f()
{
A *a = nullptr;
return a->i;
}
PS: Я считаю, что a не является odr-используемым в выражении a->i потому что он удовлетворяет условию "если" в [basic.def.odr]/4 следующим образом:
Переменная
x, имя которой отображается как потенциально вычисленное выражениеexявляется odr, используемоеexесли применение преобразования lvalue-to-rvalue (7.1) кxдает постоянного выражения (8.6), которое не вызывает никаких нетривиальных функций и, еслиxявляется объектом,exявляется элементом множества потенциальных результатов выраженияe, где либо lvalue-rvalue conversion (7.1) применяется кe, либоeявляется выражением с отбрасыванием (8.2),
В частности, выражение ex == a является элементом множества потенциальных результатов выражения e == a->i, согласно [basic.def.odr]/2 (2.3), содержащему выражение ex, где преобразование lvalue-rvalue применяется к e.