Что касается преобразования lvalue в rvalue, когда это требуется?

Я читал довольно много в Интернете, и кажется, что многие люди упоминали следующие правила (но я не мог найти его в стандарте),

Оператор сложения + (и все другие бинарные операторы) требуют, чтобы оба операнда были rvalue, а результат - rvalue. И так далее..

Я проверил стандарт C++, и в нем четко сказано, что (пункт 3.10/2),

Всякий раз, когда glvalue появляется в контексте, где ожидается prvalue, glvalue преобразуется в prvalue

(пункт 5/9),

Всякий раз, когда выражение glvalue появляется в качестве операнда оператора, ожидающего значение prvalue для этого операнда, стандартными преобразованиями lvalue-to-rvalue (4.1), array-to-pointer (4.2) или function-to-pointer (4.3) являются: применяется для преобразования выражения в значение.

Он использует термин операнд "ожидает" значение. Тем не менее, когда я смотрю на оператор сложения, оператор умножения и т. Д., Он только упоминает, что результат является предварительным значением, но ничего не говорит о том, какими "ожидаемыми" будут операнды.

Действительно ли двоичный оператор ожидает, что операнды будут prvalue, имеет значение в следующем случае,

int b = 2;
int a = b + 1;

Если ожидается, что b будет prvalue, здесь будет преобразование lvalue в rvalue, а затем он выполнит prvalue + prvalue и вернет prvalue, а результат prvalue будет присвоен lvalue a.

Однако, если b не требуется быть prvalue, это будет lvalue + prvalue, а результатом будет prvalue.

Я действительно хочу знать, где стандарт явно или неявно упоминает, что правила для разных операторов? Я проверяю все разделы операторов и только несколько операторов, которые в стандартах прямо упоминают, должны ли операнды и результаты быть lvalue или rvalue. Для большинства операторов стандарт упоминает только результат, но не требование операнда.

Благодарю.


Кстати, я обнаружил в Стандарте 5.19, что константное выражение может очень и очень неявно подразумевать, что бинарный оператор требует преобразования lvalue в rvalue для операндов. Для более подробной информации, пожалуйста, обратитесь к моему предыдущему вопросу,

смешивать использование const expr и const?

Условное выражение является константным выражением, если оно не включает одно из следующего в качестве потенциально вычисляемого подвыражения (3.2).

...

- преобразование lvalue в rvalue (4.1), если оно не применяется к

———— glvalue целочисленного типа или типа перечисления, которое относится к энергонезависимому константному объекту с предшествующей инициализацией, инициализированной с помощью константного выражения

Спасибо за прочтение.

2 ответа

Решение

Таким образом, это, как правило, одна из тех предполагаемых и плохо определенных частей стандарта; Однако в 3.10

[Примечание: некоторые встроенные операторы ожидают lvalue операндов. [Пример: все встроенные операторы присваивания ожидают, что их левые операнды будут lvalue. - конец примера] Другие встроенные операторы выдают значения r, а некоторые ожидают их. [Пример: унарные и бинарные операторы + ожидают значения rvalue и дают результаты rvalue. - конец примера] Обсуждение каждого встроенного оператора в разделе 5 указывает, ожидает ли он операндов lvalue и возвращает ли он lvalue. - конец примечания]

Обратите внимание, что плохо указанный язык "в разделе 5 указывает, ожидает ли он операндов lvalue и дает ли он lvalue".

Изучение главы 5 показывает, что перечисляются все случаи, когда выражению требуется или возвращается значение l, однако перечислено очень мало случаев, касающихся конкретно значений, я думаю, что тогда предполагается, что все остальные значения считаются значениями.

Я также подозреваю, что он плохо указан, потому что с точки зрения стандарта, это не особенно важно, если преобразование выполняется оператором неявно или явно, независимо от того, поведение должно быть последовательным и корректным.

(Прежде всего, извините за мой английский. Исправления абсолютно приветствуются)

Стандарт гласит:

§5.7-3 Результатом бинарного оператора + является сумма операндов. [...]

Давайте предположим, что у нас есть выражение e1 + e2и + выбранный оператор является встроенным, выражение правильно сформировано, e1 а также e2 есть арифметические типы или доступно приведение к арифметическому типу, и все в порядке, отлично и идеально!

Таким образом, применяется правило §5.7-3. В другой руке каждый операнд является выражением:

§5-1 [Примечание: [...] Выражение - это последовательность операторов и операндов, которая определяет вычисление. Выражение может привести к значению и может вызвать побочные эффекты. - конец примечания]

Он говорит, что выражение может привести к значению из-за void выражения, такие как delete выражение или voidфункция, но так как мы уже сказали e1 + e2 является совершенно определенным выражением!, мы можем опустить глагол "может", и поэтому мы можем подтвердить, что: выражение приводит к значению.

Последний пункт: для арифметических и логических встроенных операторов я понимаю, что, хотя он не определен стандартом, имеет значение только значение его операндов, независимо от их категории значения.

Я думаю, что с выражениями достаточно для реализации встроенного оператора + (и другие арифметические операторы), так как имеет значение только значение, и значение может быть достигнуто с помощью выражения. По этой причине Стандарт не определяет их четко.

Все таки этот тип вещей очень плохо структурирован. Например, я не нашел места, определяющего, когда оператор получает объект в качестве операнда, а не прямое значение (сомневаюсь, что я сейчас пытаюсь решить), должен ли оператор принимать его значение непосредственно для вычисления оператора, если значение является результатом оценки объекта и т. д. Очевидно, что важны только ценности, но то, что именно говорит Стандарт для этих вещей, является своего рода загадкой.

Другие вопросы по тегам