LINUX.ORG.RU

Эвалуация аргументов функции при вызове

 , ,


0

3

Есть вот такие функции:

void whatever(std::vector<int> lhs, bool rhs);
bool check(const std::vector<int> &v);

Вызываются вот так:

std::vector<int> arg{1, 2, 3};
whatever(std::move(arg), check(arg));

Понятно, что

Order of evaluation of the operands of almost all C++ operators (including the order of evaluation of function arguments in a function-call expression and the order of evaluation of the subexpressions within any expression) is unspecified.

Вопрос скорее о том, чем в данном случае является результат Эвалуации std::move(arg)? Обьект std::vector<int> или же rvalue-reference (std::vector<int>&&)?

★★★★★

Последнее исправление: KennyMinigun (всего исправлений: 3)

Ответ на: комментарий от RazrFalcon

Эвалуация аргументов функции при вызове

при вызове

При коллинге же, ну

Crocodoom ★★★★★
()

In particular, std::move produces an xvalue expression that identifies its argument t. It is exactly equivalent to a static_cast to an rvalue reference type.

Стало быть, rvalue-reference

harvos
()

Вопрос скорее о том, чем в данном случае является результат Эвалуации std::move(arg)?

Результат — объект arg. (http://eel.is/c draft/expr#def:result,glvalue: The result of a glvalue is the entity denoted by the expression.)

utf8nowhere ★★★
()
Последнее исправление: utf8nowhere (всего исправлений: 1)
Ответ на: комментарий от harvos

In particular, std::move produces an xvalue expression that identifies its argument t.

Если аргумент это функция, то std::move produces an lvalue expression.

utf8nowhere ★★★
()
Ответ на: комментарий от harvos

Eсли взять std::move без контекста, то да. Однако, в сабжевом вопросе идется про аргумент функции.

И что-то мне позсказывает, что суть идется о вычислении того, что ложится «в стек». Т.е. если функция ожидала бы rvalue-reference, то в стек бы попал указатель (ну, в типичной реализации ссылок через указатели). Так и в данном случае, в стек надо положить обьект std::vector.

Но все же хочется убедиться, ибо в стандарте я не осилил найти.

KennyMinigun ★★★★★
() автор топика

Вопрос скорее о том, чем в данном случае является результат Эвалуации std::move(arg)?

А какая разница?

[expr.call] p8
The initialization of a parameter, including every associated value computation and side effect, is indeterminately sequenced with respect to that of any other parameter.

Т.е. результат move() всё равно в итоге будет использован при инициализации, которая может происходить в любом порядке, в том числе и в «плохом».

xaizek ★★★★★
()
Последнее исправление: xaizek (всего исправлений: 1)
Ответ на: комментарий от utf8nowhere

Ну, по крайней мере, теперь я уверен, что сабжевый пример — UB.

А мои рассуждения — лишь спекуляция на основе возможной реализации.

KennyMinigun ★★★★★
() автор топика
Последнее исправление: KennyMinigun (всего исправлений: 1)
Ответ на: комментарий от utf8nowhere

Не вижу тут UB.

Ок, код выше может работать не так, как планировалось. Т.е. в check попадет константая ссылка* на обьект std::vector<int> в «valid but unspecified state».

Эвалуация аргументов функции при вызове (комментарий)

Т.е. результат move() всё равно в итоге будет использован при инициализации, которая может происходить в любом порядке, в том числе и в «плохом».

* была опечатка в примере, исправил.

KennyMinigun ★★★★★
() автор топика
Последнее исправление: KennyMinigun (всего исправлений: 2)

Прочёл как «овуляция».

anonymous
()

эвалуация у тебя в штанах

anonymous
()
Ответ на: комментарий от KennyMinigun

В specified, это ж вектор. Останется пустой вектор.

harvos
()

Лол :-) А почему бы просто не выполнить эвалуацию вот так:

std::vector<int> arg{1, 2, 3};
check(arg);
whatever(std::move(arg), arg);
и заниматься более интересными делами, чем эвалуировать стандарт цепепе? :-) Лол :-)

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.