Это неопределенное поведение:Порядок оценки параметров функции: это UB, если мы передаем ссылку?
void feedMeValue(int x, int a) {
cout << x << " " << a << endl;
}
int main() {
int a = 2;
int &ra = a;
feedMeValue(ra = 3, a); // equivalent to: feedMeValue(a = 3, a) (see note bellow)
return 0;
}
, потому что в зависимости от того, что параметр получает оценку первым мы могли бы назвать (3, 2)
или (3, 3)
.
Однако это:
void feedMeReference(int x, int const &ref) {
cout << x << " " << ref << endl;
}
int main() {
int a = 2;
int &ra = a;
feedMeReference(ra = 3, a); // equivalent to: feedMeReference(a = 3, a) (see note bellow)
return 0;
}
будет всегда выводится 3 3
, так как второй параметр является ссылкой и все параметры были оценены перед вызовом функции, так что даже если второй параметр вычисляется до не после ra = 3
, то функция получила ссылку на a
, которая будет иметь значение 2
или 3
во время оценки, но всегда будет иметь значение 3
во время вызова функции.
Это второй пример UB? Важно знать, потому что компилятор может свободно что-либо делать, если обнаруживает неопределенное поведение, даже если я знаю, что он всегда даст те же результаты.
Примечание: Я оставлю feedMeReference(ra = 3, a)
так как некоторые ответы ссылаются ra
, но следует иметь в виду, что проще эквивалентная проблема это, если мы называем feedMeReference(a = 3, a)
(проще, потому что мы исключаем ra
что только на пути нашего issue (второй параметр является ссылкой)).
Как ваш компилятор это он, я предполагаю, что это будет выбор в пользу максимальной иррациональности. – Bathsheba
@ Батшеба, да, я, как правило, персонифицирую компилятор. – bolov
удалил локальную ссылку «ra», потому что я не думаю, что она имеет значение, и акцент делается на втором параметре, который является ref или нет. – bolov