Параметр OUT не соответствует документации

На веб-сайте Emba указано, что параметр OUT (не указано, какой тип, поэтому я предполагаю, что он применим ко всем типам) не должен использоваться для ввода, поскольку его значение «отбрасывается».
Под словом «отброшено» я понимаю (хотя мы и не на уроке изучения Библии), что значение обнуляется.

Однако с параметром out начальное значение переменная отбрасывается подпрограммой, которой она передается.

Но этот простой код показывает, что значение, хранящееся в «i», не отбрасывается, а в «s»:

TYPE TMyRec = record
  i: Integer;
end;

Procedure TestInteger(OUT i: Integer);
Begin
End;

Procedure TestRec(OUT R: TMyRec);
Begin
End;

Procedure TestStr(OUT S: string);
Begin
End;

procedure TfrmTest.btnTestRecClick(Sender: TObject);
begin
  VAR MyRecord: TMyRec;
  MyRecord.i:= 7;
  TestRec(MyRecord);
  Memo.Lines.Add('Test rec: '+ IntToStr(MyRecord.i));
end;

procedure TfrmTest.btnTestStrClick(Sender: TObject);
begin
  VAR s: string:= 'x';
  TestStr(s);
  Memo.Lines.Add('Test str: '+ s);
end;

procedure TfrmTest.btnTestIntClick(Sender: TObject);
begin
  VAR i: Integer:= 7;
  TestInteger(i);
  Memo.Lines.Add('Test int: '+ IntToStr(i));
end;

Итак, документация неверна? Просто формулировка неверна? Может быть, они имели в виду «проигнорировать», а не «отбросить»?

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

USauter 17.11.2022 16:20

Отброшено не то же самое, что очищено. Вы можете найти дополнительную информацию о поведении наших параметров на delphisorcery.blogspot.com/2021/04/… и dalijap.blogspot.com/2021/03/…

Dalija Prasnikar 17.11.2022 16:21

@DalijaPrasnikar - Прямо в этом разделе они ясно говорят, что очищают память. Не так ли? "Вызов GetInfo сразу освобождает память"

Server Overflow 17.11.2022 16:24

Если вы поместите слово «отброшено» в строку между «проигнорировано» и «очищено», я думаю, что слово «отброшено» почти коснется «очищено».

Server Overflow 17.11.2022 16:26

@ServerOverflow: бесплатно <> заполнить нулями. Если у вас есть type TX = class A: Integer; end; var X: TX; begin X := TX.Create; try X.A := 394; finally X.Free; end;, то вы явно «свободны» X, но, скорее всего, X.A будет 394 некоторое время, пока память не будет перезаписана чем-то другим (что может быть в любой момент — вы НЕ ДОЛЖНЫ использовать (старый объект указывает на by) X после освобождения).

Andreas Rejbrand 17.11.2022 16:30

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

Dalija Prasnikar 17.11.2022 16:32

Я думаю, что они хотели сказать "не учитываются" вместо "отбрасываются".

Server Overflow 21.11.2022 16:32
google.com/search?q=define:discarded — «Чтобы избавиться от чего-то, как от не нужного».
Server Overflow 21.11.2022 16:34
Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
8
197
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Украшение параметра out означает, что параметр будет использоваться только для возврата значения вызывающей стороне; подпрограмма не должна делать никаких предположений о начальном значении параметра.

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

Однако нет никакой гарантии, что «переданное» значение действительно будет очищено. В конце концов, такая гарантия бесполезна; напротив, это, скорее всего, заставит компилятор генерировать немного менее эффективный код (поскольку обнуление памяти требует времени).

Подумайте о производителе часов, который делает часы, способные нормально функционировать при температуре до -50°C. Затем вы делаете заказ на часы, которые должны нормально функционировать только при температуре до -20°C. Производитель может использовать эти знания для удешевления производства часов. Тем не менее, нет абсолютно никакой гарантии, что часы, которые вам доставят, сломаются при температуре -50°C, и вам, как правило, такая гарантия не требуется. (Но, конечно, вы не должны использовать часы при температуре ниже -20°C.)

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

Ну, поскольку программист никогда не использует это значение, оно эффективно «отбрасывается», не так ли?

Чуть позже на той же странице:

Вызов GetInfo немедленно освобождает память, используемую MyRecord, прежде чем управление программой перейдет к процедуре.

Ладно, это трудно не считать ошибочным.

"Ладно, это трудно не считать ошибочным" - Верно! Эмба четко говорит, что запись очищена (но это не так). Я распространил эту ошибочную информацию на все типы, переданные как Out.

Server Overflow 17.11.2022 16:21

@ServerOverflow: На самом деле «очистить» <> «бесплатно». Обычно, когда что-то «освобождается», память некоторое время остается неповрежденной, прежде чем она будет перезаписана, что может стать в любое время. Он не заполняется нулями. Все-таки я не понимаю, что Эмба вообще имеет в виду под "бесплатным" здесь

Andreas Rejbrand 17.11.2022 16:26

Возможно, они использовали free, чтобы подчеркнуть, что вы не можете передавать какое-либо входное значение через параметр out. Кажется, это просто неудачный выбор слов.

Dalija Prasnikar 17.11.2022 16:35

«поскольку программист никогда не использует это значение, оно эффективно отбрасывается» — лично я бы использовал более подходящее слово, например, «игнорировать».

Server Overflow 22.11.2022 08:47

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

TYPE TMyRec = record
  i: Integer ;
  class operator Initialize (out Dest: TMyRec);
end;

class operator TMyRec.Initialize (out Dest: TMyRec);
begin
  dest.i := 0;
end;

Это скорее комментарий, но код плохо форматируется в комментариях.

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