Что происходит, когда мы передаем по значению-результат в этой функции? - PullRequest
1 голос
/ 01 мая 2019

Рассмотрим этот код.

foo(int x, int y){
    x = y + 1;
    y = 10;
    x++;
}
int n = 5;
foo(n,n);
print(n);

если мы предположим, что язык поддерживает передачу по значению, каков будет ответ? Насколько я знаю, результат передачи по значению копируется внутрь и наружу. Но я не уверен, что будет значением n, когда оно копируется в два разных формальных параметра. Должны ли x и y действовать как ссылки? Или n должен получить значение x или y в зависимости от того, что было скопировано последним?

Спасибо

1 Ответ

2 голосов
/ 01 мая 2019

Независимо от того, является ли это общим результатом передачи по значению или результатом передачи по значению, тогда x и y станут отдельными копиями из n, они никоим образом не являютсяпривязаны друг к другу, за исключением того факта, что они начинаются с одного и того же значения.

Однако, результат передачи по значению присваивает значение исходным переменным при выходе из функции, что означает, что n будет приниматьзначение x и y. Какой тот, который он получает первым (или, что более важно, последним, поскольку это будет его окончательное значение), открыт для интерпретации, поскольку вы не указали, какой язык вы на самом деле используете.

На странице Википедии этой записи есть что сказать по этому вопросу («вызов за копированием-восстановление» - это терминология того, о чем вы спрашиваете, и я подчеркнул важный момент иперефразируя, чтобы сделать его более понятным):

Семантика call-by-copy-restore также отличается от семантики call-by-reference, где два или более аргумента функции накладываются друг на друга;то есть указывать на ту же переменную в среде вызывающего.

При вызове по ссылке запись в одну из них немедленно повлияет на другую;call-by-copy-restore позволяет избежать этого, предоставляя функции отдельные копии, но оставляет результат в среде вызывающей стороны неопределенным в зависимости от того, какой из псевдонимов аргументов копируется обратно первым.Будут ли копии сделаны в порядке слева направо как при въезде, так и при возврате?

Я бы надеялся , что спецификация языка прояснит фактическуюнепротиворечивое поведение, чтобы избежать всех тех углов неопределенного поведения, которые вы часто видите в C и C ++: -)

Изучите приведенный ниже код, слегка измененный по сравнению с вашим оригиналом, поскольку я по своей природе ленив и не хочудолжны вычислить окончательные значения: -)

foo(int x, int y){
    x = 7;
    y = 42;
}
int n = 5;
foo(n,n);
print(n);

Ближайшие возможности, которые я считаю наиболее вероятными:

  • строгое копирование при выходе слева направо, n станет x, затем y, поэтому 42.
  • будет строгое копирование при выходе справа налево, n станет y, затем x, поэтому 7.
  • неопределенное поведение, n может принимать либо, либо, возможно, любое значение .
  • компилятор вызывает диагностику и отказывается от компиляции, если у него нет строгих правили не хочет, чтобы ваш код в конечном итоге вел себя (на первый взгляд) случайным образом.
...