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

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

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 в зависимости от того, что скопировано последним?

Спасибо


person Huzo    schedule 01.05.2019    source источник
comment
Что это за язык?   -  person Tim Biegeleisen    schedule 01.05.2019
comment
@TimBiegeleisen на любом выдуманном языке. Это не имеет значения. Вы можете только предположить, что язык использует результат передачи по значению   -  person Huzo    schedule 01.05.2019


Ответы (1)


Вне зависимости от того, обычный это pass-by-value или pass-by-value-result, тогда x и y стали бы отдельными копиями n, они никак не связаны друг с другом, кроме на самом деле они начинаются с одного и того же значения.

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

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

Семантика 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.
  • undefined, n может принимать одно или, возможно, любое значение.
  • компилятор вызывает диагностику и отказывается компилировать, если у него нет строгого правила и он не хочет, чтобы ваш код в конечном итоге вел себя (на первый взгляд) случайным образом.
person paxdiablo    schedule 01.05.2019
comment
Понятно, но вы упомянули только передачу по значению. А как насчет части результатов? x и y могут иметь разные копии n, но поскольку результат передачи по значению также копируется, n должно иметь обновленное значение. Вопрос в том, каким должно быть это значение, учитывая свойства значения передачи по результату, которое представляет собой комбинацию передачи по значению и передачи по результату. - person Huzo; 01.05.2019
comment
Теперь я вижу. То есть вы говорите, что какое значение копировать, зависит от свойств языка и что нет нормативного способа сделать это в технике передачи по значению-результату? - person Huzo; 01.05.2019