Может ли ссылка на функцию Фортрана мешать назначению?

Я знаю, что (по крайней мере, в какой-то момент) следующее недопустимо на Фортране из-за псевдонимов

program main

integer :: x, y

! compilers assume a and b to be distinct
y = f(x, x)

contains

integer function f(a, b) result(c)
  integer, intent(in out) :: a, b
  a = 1
  b = 2
  c = a ! compiler can optimize to c = 1
end function

end program main

Но справедливо ли следующее?

program main

integer :: x(3)

x = [1, 2, 3]
x = square_me(x)

contains

function square_me(a) result(squared)
  integer, intent(in out) :: a(3)
  integer                 :: squared(3)

  squared = a ** 2
  a(1) = 0 ! nasty side-effect
end function

end program main

Он работает в gfortran, но я не уверен, соответствует ли он стандартам.

Я знаю, что побочные эффекты в функциях — не очень хорошая идея. Я имею дело с более чем 100 тысячами строк устаревшего кода, который любит использовать функции, возвращающие целочисленный код в стиле C, и изменять аргументы, поэтому этот вопрос касается именно стандарта.

Какой аспект вас беспокоит? (Я могу догадаться, но в откровенности нет никакого вреда.)

francescalus 18.04.2024 21:45

Какими бы ни были опасения, я бы настоятельно не советовал использовать функции с побочными эффектами, это просто напрашивается на проблемы. В таких случаях используйте подпрограммы. Сохраняйте свои функции в чистоте.

Ian Bush 18.04.2024 22:09

@IanBush Комментарий «неприятный побочный эффект» должен был передать эту идею :)

Adam 18.04.2024 22:39

@francescalus Я был обеспокоен тем, что компилятор попытается поделиться ссылками на возвращаемую x и результирующую переменную squared. Другими словами, я знаю, что сначала оценивается правая часть, но когда речь идет о массивах, я менее уверен в том, что говорит стандарт (в частности, я наблюдал много статического распределения в этой программе).

Adam 18.04.2024 22:49

Неважно, было ли это предназначено для передачи идеи. Совету @IanBush следует прислушаться. Что касается вашего первого примера, это неверный Фортран. Компилятор может делать все, что захочет, включая установку c = 1. Ваш второй пример не предполагает псевдонимов.

steve 18.04.2024 22:51

@Стив -1. Есть много веских причин задавать вопросы, когда вы знаете, что что-то плохо, но все равно нуждаетесь в ответе. «Просто не делайте этого» бесполезно для тех, кто пытается интерпретировать, редактировать и улучшать код, созданный десятилетиями.

Adam 18.04.2024 22:58

Конечно. Также важно правильно сформулировать вопрос. Второй пример кода не имеет никакого отношения к псевдонимам.

steve 18.04.2024 23:27

@ Адам, я понимаю, почему ты спрашиваешь, и даже если язык не идеален, мне кажется, это разумный вопрос, ведь одна из причин спрашивать - это научиться. Но цель моего предыдущего комментария состоит в том, чтобы донести до кого-то, кто смотрит на это новичком, что, хотя, при осторожном подходе, подобные вещи могут быть разрешены, это очень плохая идея.

Ian Bush 18.04.2024 23:35

Если бы я все еще не участвовал в забастовке избирателей, я бы обязательно проголосовал за этот и подобные вопросы. Цель вопроса ясна, и любое заблуждение, вызванное (неправильным) использованием терминологии, полностью соответствует теме вопросов и ответов на этом сайте.

francescalus 19.04.2024 00:25

@francescalus, намерение ясно? Вопрос в заголовке касается псевдонимов. Название вводит в заблуждение. Фактически речь идет о функциях с побочными эффектами.

steve 19.04.2024 02:37

@steve, мы с тобой знаем ответ, и мы с тобой не задали бы вопрос. Ответом на точный вопрос, заданный в заголовке, вполне может быть «нет», но, возможно, это будет ужасный ответ. Побочные эффекты и псевдонимы настолько тесно связаны, что, если мы отклоняем какой-либо вопрос, который сбивает их с толку, мы упускаем почти любую возможность уточнить его. Точно задать вопрос об этом случае — значит усомниться в этом.

francescalus 19.04.2024 02:51

@francescalus, я не предлагаю отклонять вопрос. Я предлагаю исправить название, чтобы оно отражало реальность. Если кто-то ищет ответы о побочных эффектах, я сомневаюсь, что он будет использовать «псевдоним» в качестве поискового запроса.

steve 19.04.2024 04:11

@steve, лучше?

francescalus 19.04.2024 13:29

@steve Теперь я понимаю, что название довольно глупо с учетом информации, которую я здесь узнал, но чтобы дать ему немного перспективы: Фортран (относительно) уникален тем, что аргументы передаются по ссылке, и поскольку Фортран «возвращает» результаты по присваивая результирующей переменной (имя функции или что-то еще), я думал, что возможно, что результаты также «возвращаются по ссылке» - я недостаточно хорош в стандартах, чтобы выяснить это самостоятельно, поэтому я подумал, что второй пример может быть недействительным для псевдонимов.

Adam 19.04.2024 14:08

@francescalus, намного лучше. Хотя отмечу, что правая часть полностью оценивается перед назначением левой, поэтому побочный эффект не может вызвать проблемы в коде y = f(x,x). Фортран 2023, 10.1.4, вероятно, более важен для выражения в правой части, т. е. y = f(x,x) + x. В данном случае побочный эффект может испортить последнее дополнение (см. примечание 1). Обратите внимание: Фортран позволяет переупорядочить оценку, например y = x + f(x,x), где x инициализирует аккумулятор, а затем f(,x,x) вычисляется и добавляется в аккумулятор.

steve 19.04.2024 19:27
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
15
102
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ни одна из основных программ недействительна.

Под так называемыми правилами псевдонимов в Фортране обычно подразумеваются те ограничения, которые применяются к объектам во время выполнения процедуры. Однако в операторе присваивания оценка правой части полностью выполняется до того, как будет затронута левая часть.

Вместо этого вторую основную программу ломает ограничение на побочные эффекты функций.

Побочный эффект ограничен (F2018, 10.1.4) тем, что, за исключением некоторых случаев, здесь не применимых:

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

Присваивание a(1) вызывает определение фактического аргумента x, поэтому x может не появляться где-либо еще в операторе присваивания (включая левую часть).

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

Получается, что функции могут (но, конечно, не должны) выполнять побочные эффекты со своими аргументами, пока эти аргументы не встречаются в операторе несколько раз? (либо цель назначения, либо что-то вроде z = foo(x) + foo(x)) АКА без назначения a, это действительно?

Adam 18.04.2024 22:43

Есть эффекты, которые продолжаются за пределами утверждения, в котором возникает побочный эффект. Они слишком тонкие для комментариев и выходят за рамки этого вопроса, но подпадают под правило «даже если вы знаете правила, не предполагайте, что другие люди знают». Действительно, побочные эффекты в функциях неприятны.

francescalus 18.04.2024 22:47

Я бы, может быть, даже зашел так далеко, что сказал, что вопрос SO, спрашивающий: «Каковы ограничения на побочные эффекты в функциях Фортрана?» будет закрыт как слишком широкий.

francescalus 18.04.2024 23:00

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

Выбросить основные, т.е. не перехваченные результаты исключения в SIGSEGV
Почему типом результата условного выражения является константная ссылка?
Указано ли в стандарте C++ «Побочные эффекты функции упорядочиваются перед ее вычислением»?
Clang не удается создать экземпляр `operator!=()` из `operator==()` с типом возвращаемого значения `auto` для объекта класса, переданного через параметр шаблона, не относящийся к типу
Почему Rust не меняет порядок полей в перечислении для размещения в памяти?
Почему C++23 if consteval не допускает разные типы возврата, как если бы constexpr подходил?
В C++ все подвыражения аргументов вызова функции последовательно упорядочены?
Каковы точные условия, при которых оценивается type_name в sizeof(type_name)? GCC оценивает f() в sizeof(int [(f(), 100)])
Можете ли вы объявить указатель C с собственным адресом?
Почему выражение с запятой, используемое в качестве размера массива, должно быть заключено в круглые скобки, если оно является частью декларатора массива?