L-значения, которые не обозначают объекты в C ++ 14
Я использую N3936 в качестве ссылки здесь (пожалуйста, исправьте этот вопрос, если какой-либо текст C ++ 14 отличается).
До 3,10Lvalues и rvalues у нас есть:
Каждое выражение относится к одной из основных классификаций в этой таксономии: lvalue, xvalue или prvalue.
Однако определениеименующий гласит:
именующий [...] обозначает функцию или объект.
В 4.1Преобразование Lvalue в Rvalue появляется текст:
[...] Во всех других случаях результат преобразования определяется по следующим правилам: [...] В противном случае значение, содержащееся в объекте, указанном в glvalue, является результатом предварительного вычисления.
Мой вопрос: что происходит в коде, где lvalue не обозначает объект? Есть два канонических примера:
Пример 1:
int *p = nullptr;
*p;
int &q = *p;
int a = *p;
Пример 2:
int arr[4];
int *p = arr + 4;
*p;
int &q = *p;
std::sort(arr, &q);
Какие линии (если есть) плохо сформированы и / или вызывают неопределенное поведение?
Ссылаясь на Пример 1: есть*p
lvalue? По моей первой цитате это должно быть. Тем не менее, моя вторая цитата исключает это, так как*p
не обозначает объект. (Это, конечно, не xvalue или prvalue).
Но если вы интерпретируете мою вторую цитату, чтобы означать, что*p
на самом деле это lvalue, то он вообще не подпадает под правила преобразования lvalue в rvalue. Вы можете принять правило всеобщего охвата, что «все, что не определено Стандартом, является неопределенным поведением», но тогда вы должны разрешить существование пустых ссылок, если не выполняется преобразование lvalue в rvalue.
История: Этот вопрос был поднят вDR 232 , В C ++ 11 разрешение от DR232 действительно появилось. Цитата из N3337Преобразование Lvalue в Rvalue:
Если объект, на который ссылается glvalue, не является объектом типа T и не является объектом типа, производного от T, или если объект не инициализирован, программа, для которой требуется это преобразование, имеет неопределенное поведение.
который по-прежнему разрешает существование пустых ссылок - он только устраняет проблему выполнения преобразования lvalue в rvalue для одного из них.Также обсуждается в этой теме
Разрешение от DR232 больше не появляется в N3797 или N3936, хотя.