OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Воскресенье, 28 Апрель, 2024 22:25

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 70 ]  На страницу Пред.  1, 2, 3, 4  След.
Автор Сообщение
 Заголовок сообщения:
СообщениеДобавлено: Вторник, 02 Май, 2006 20:48 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Цитата:
Пример я и сам могу придумать.

Это был не надуманный пример. В Дельфе действительно много стандартных процедур было написано именно в стиле передачи структур или строк через стек копированием (предопределенная переменная result). И использовались они в коде сплошь и рядом...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Среда, 03 Май, 2006 09:21 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Цитата:
Включи фантазию. Можно, например, делать все так же как в обероне - передавать указатель на непроиниченную структуру. Только делать это будет компилятор. Принципиальную разницу объяснять не надо?

Нафантазировать можно много чего... Зачем смешивать разные механизмы - передачу через стек и по ссылке? Одни ругаются, что низкий уровень недоступен, но когда предлагается прозрачный сиснтаксис, который абсолютно высокоуровнев, но позволяет программисту чувствовать и контроллировать то, что происходит в сгенерированном коде, другие начинают кричать, что "мало автоматизации"...
Много ли компиляторов поддерживают такую оптимизацию? Где гарантии, что код, написанный с надеждой на эту оптимизацию, на другом компиляторе не потеряет в производительности раза в два (а такое реально)? Так я вижу, что происходит, и знаю, что где бы не откомпилировал программу, при выполнении будет происходить одно и то же.
Опять же, многие ли из компиляторов С++ не имеют каких-нибудь общеизвестных ошибок, именно из-за непоследовательности и навороченности языка? Те же возможности можно было реализовать и гораздо более стройно, просто приняв принцип "одна возоможность - только один способ ее использовать..."


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Среда, 03 Май, 2006 11:48 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 18:55
Сообщения: 2272
Откуда: Россия, Нижний Новгород
Vlad писал(а):
Непроиниченные мемберы.

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

А в шарпе?

Произвольных.
Vlad писал(а):
В таком случае это прореха в дизайне языка, которую пытаются решить еще одной прорехой. Если бы язык позволял возвращать структуры, то непроиниченные структуры не имели бы смысла (а, следовательно, в случае правильного использования не было бы никакого реального perfomance fault).

Всё верно, но вывод надо сделать противоположный. Вот язык C# разрешает возвращать структуры. Конструктор структуры "new Data()" как раз эту самую структуру и возвращает. Непроинициализированных структур в C# не бывает. Результат - потеря производительности, которую я вчера продемонстрировал в сообщении от: "Вт Май 02, 2006 2:11 pm".

По поводу возвращения структур из функций можно привести пример с комплексными числами в C#. Естественно, процедура в которую комплексные числа передаются и забираются по ссылке работает быстрее чем функция из которой возвращается копия структуры комплексного числа. Я когда-то об этом ещё на РСДН-е писал. Там народ предложил дожидаться когда Микрософт свой JIT компилятор до ума доведёт.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Среда, 03 Май, 2006 12:18 

Зарегистрирован: Вторник, 25 Апрель, 2006 16:21
Сообщения: 2180
Откуда: Нижний Новгород
> ... то их возвращали бы везде, где не лень, потому что форма
> записи действительно удобнее. Отсюда лишние тормоза, т.к.
> безобидная запись a := GetSomeRec() (а таковые в той же Дельфе
> пишутся обычно сплошь и рядом) вызывает два лишних
> копирования - сначала в стек внутри процедуры, потом из стека в
> ту переменную, которой присваивается...

А чем вот этот вариант (извиняюсь за С, синтаксис языков Вирта пока знаю плохо, никак руки не дойдут):
struct flags {
char flag_a;
char flag_b;
};

flags GetFlag()
{
...
return MyFlag;
}

Хуже (тормознее) чем скажем какая-нибудь:
double GetMagicNumber() {return magic;}

?

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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Среда, 03 Май, 2006 12:46 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Цитата:
А чем вот этот вариант (извиняюсь за С, синтаксис языков Вирта пока знаю плохо, никак руки не дойдут):
struct flags {

Он тормознее, чем работа по ссылке:
void GetFlag (flag &f),
PROCEDURE GetFlag(OUT f: Flag)
потому что здесь процедура напрямую пишет в поля выходного параметра, в то время как в вашем случае она сначала копирует 8 байт (с учетом выравнивания структуры) в стек инструкцией return, а затем еще раз - из стека для присваивания какой-либо переменной после возврата из функции. На малой структуре разница невелика. На большой - в разы.
Если, конечно, не помечтать об суперумной оптимизации, которая когда-нибудь, может быть, появится :-)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Среда, 03 Май, 2006 12:53 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Цитата:
Кроме того, мне кажется что если уж класс - это тип определенный пользователем, то и разрешенное множество операций с этим типом должно быть таким же как и с базовыми (предопределенными) типами.
Просто для того чтобы не множить сущности.

Это - мощная идея, у нее есть много плюсов, но есть и минусы... Так или иначе, в Обероне перегрузки операций и обобщенки нет. В большинстве случаев особых неудобств это не приносит. Даже тем, кто программирует численные алгоритмы и др. научные вещи - а среди этого контингента КП&ББ распространен пока больше всего. Притом переходит на него этот народ, именно устав "долбаться" с С++.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Среда, 03 Май, 2006 14:34 

Зарегистрирован: Вторник, 25 Апрель, 2006 16:21
Сообщения: 2180
Откуда: Нижний Новгород
Илья Ермаков писал(а):
Цитата:
А чем вот этот вариант (извиняюсь за С, синтаксис языков Вирта пока знаю плохо, никак руки не дойдут):
struct flags {

Он тормознее, чем работа по ссылке:
void GetFlag (flag &f),
PROCEDURE GetFlag(OUT f: Flag)


Да, но по крайней мере в C/C++ работа (изменение значения) по ссылке - плохая идея с т.з. синтаксиса. Т.к. отличить просто параметр от того что функция должна будет изменить, просто не реально при использовании такой функции.
Например:
GetFlag(MyFlag);
Ничем не будет (синтаксически) отличаться от
SetFlag(MyFlag);
Хотя это ПРИНЦИПИАЛЬНО разные действия (SetFlag(flag f)).

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

Каков синтаксис использования таких конструкций в Обероне/КП?

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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Среда, 03 Май, 2006 15:47 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Илья Ермаков писал(а):
Нафантазировать можно много чего... Зачем смешивать разные механизмы - передачу через стек и по ссылке?


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

Илья Ермаков писал(а):
Одни ругаются, что низкий уровень недоступен, но когда предлагается прозрачный сиснтаксис, который абсолютно высокоуровнев, но позволяет программисту чувствовать и контроллировать то, что происходит в сгенерированном коде, другие начинают кричать, что "мало автоматизации"...


Это ты про оберон? Не согласен, я уже говорил. Полный контроль над сгенерированным кодом есть в С и с большими оговорками в С++.

Илья Ермаков писал(а):
Много ли компиляторов поддерживают такую оптимизацию?


Даже борланд это умеет. Правда не без бзиков (помню ему было принципиально пишется ли Object o = getObject() или Object o(getObject())).

Илья Ермаков писал(а):
Где гарантии, что код, написанный с надеждой на эту оптимизацию, на другом компиляторе не потеряет в производительности раза в два (а такое реально)?


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

Илья Ермаков писал(а):
Опять же, многие ли из компиляторов С++ не имеют каких-нибудь общеизвестных ошибок, именно из-за непоследовательности и навороченности языка?


Ошибки кодогенерации у популярных компиляторов надо поискать. Хотя я сталкивался и на VC6 (один раз) и на борланде (несколько раз).

Илья Ермаков писал(а):
Те же возможности можно было реализовать и гораздо более стройно, просто приняв принцип "одна возоможность - только один способ ее использовать..."


Это очень ограничивает. Я не хочу мыслить в терминах типичной машинной архитектуры при решении моих прикладных задач. Мне это никак не помогает. Все bottle-neck'и на моей практике упирались не в копирование объектов или т.п. "особенности реализации", а в используемые алгоритмы и ограничения системного API. И решались эти проблемы соответственно.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Среда, 03 Май, 2006 18:25 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Сергей Губанов писал(а):
Просто их инициализация может быть очень хитро отложена так, что компилятор до этого сам точно не додумается и потребует чтобы они были проинициализированы на всякий пожарный случай ещё и преждевременно, т.е. дважды.


Почему бы не рассматривать такую "хитрую" инициализацию как повод к редизайну?

Сергей Губанов писал(а):
Vlad писал(а):
А в шарпе?

Произвольных.


Значит для шарпа твой пример некорректен и говорить о каком-то perfomance fault'е не приходится.

Сергей Губанов писал(а):
Всё верно, но вывод надо сделать противоположный. Вот язык C# разрешает возвращать структуры. Конструктор структуры "new Data()" как раз эту самую структуру и возвращает. Непроинициализированных структур в C# не бывает. Результат - потеря производительности,


Ты не понял. В C# твой пример не имеет смысла, т.к. нет необходимости передавать неинициализированную (инициализированную по умолчанию) структуру куда-либо, можно сразу вернуть проинициализированную нужными (недефолтовыми) значениями.

Сергей Губанов писал(а):
Там народ предложил дожидаться когда Микрософт свой JIT компилятор до ума доведёт.


Если это так, то это очень неплохой совет, по сравнению с ручной работой, которую никто не оценит (какова вероятность, что bottle-neck будет именно в этом?).


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Среда, 03 Май, 2006 18:41 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Илья Ермаков писал(а):
Он тормознее, чем работа по ссылке:


Я настаиваю на том, что такое утверждение некорректно без указания конкретного компилятора.

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


Уже давно появилась. VC7.1:
Код:
struct flags {
char flag_a;
char flag_b;
};

flags GetFlag1()
{
flags result;
    result.flag_a = 1;
    result.flag_b = 2;
    return result;
}

void GetFlag2(flags& result)
{
    result.flag_a = 1;
    result.flag_b = 2;
}

int main()
{
flags flags1 = GetFlag1();
flags flags2;
    GetFlag2(flags2);

    return flags1.flag_a + flags2.flag_a;
}


Код:

_main   PROC NEAR                   ; COMDAT

; 22   : flags flags1 = GetFlag1();
; 23   : flags flags2;
; 24   :     GetFlag2(flags2);
; 25   :
; 26   :     return flags1.flag_a + flags2.flag_a;

    mov eax, 2

; 27   : }

    ret 0
_main   ENDP



Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Среда, 03 Май, 2006 19:17 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Илья Ермаков писал(а):
Даже тем, кто программирует численные алгоритмы и др. научные вещи - а среди этого контингента КП&ББ распространен пока больше всего. Притом переходит на него этот народ, именно устав "долбаться" с С++.


Этому есть вполне естественное объяснение. У такого контингента нет времени на изучение "особенностей" С++ и нет возможности применить эти знания (на численных алгоритмах).


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Среда, 03 Май, 2006 21:27 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Код:
_main   PROC NEAR                   ; COMDAT

; 22   : flags flags1 = GetFlag1();
; 23   : flags flags2;
; 24   :     GetFlag2(flags2);
; 25   :
; 26   :     return flags1.flag_a + flags2.flag_a;

    mov eax, 2

; 27   : }

Не понял, поясни пример... Показываешь, что на каждую инструкцию приходится по одной машинной? Ну так лишняя инструкция возникает не в main, а при возврате значения из процедуры. И оптимизатор не поможет, т.к. код процедуры генерируется один, а контекстов, в которых она вызывается - много, и под конкретное присваивание ничего не подгонишь. Если только не inline...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Среда, 03 Май, 2006 21:47 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Илья Ермаков писал(а):
Не понял, поясни пример...


Я специально пытался написать нетривиальный код, чтобы его не выкинул оптимизатор. Однако он его все равно выкинул. Тогда я подумал - зачем пытаться обмануть оптимизатор, когда и этот пример сам по себе показателен. И запостил сюда.

Илья Ермаков писал(а):
а контекстов, в которых она вызывается - много, и под конкретное присваивание ничего не подгонишь.


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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 04 Май, 2006 10:42 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Alexey Veselovsky писал(а):
Да, но по крайней мере в C/C++ работа (изменение значения) по ссылке - плохая идея с т.з. синтаксиса. Т.к. отличить просто параметр от того что функция должна будет изменить, просто не реально при использовании такой функции.
Например:
GetFlag(MyFlag);
Ничем не будет (синтаксически) отличаться от
SetFlag(MyFlag);
Хотя это ПРИНЦИПИАЛЬНО разные действия (SetFlag(flag f)).

Да, согласен, в С++ это не красиво. Как в Обероне? В Обероне и в том, и в другом случае принято передавать структуру по ссылке, только "ссылки" бывают разные: VAR, IN, OUT, что позволяет явно указать, для чего передается ссылка на данные - для их изменения, только для чтения (тогда изменение внутри процедуры будет запрещено) или подчеркнуть то, что на входе данные могут быть неопределенными (но чтение все равно не запрещается).
PROCEDURE GetFlag(OUT f: MyFlag);
PROCEDURE SetFlag(IN f: MyFlag);
Таким образом, вызов двух таких процедур тоже "синтаксически никак не будет отличаться" (GetFlag(f), SetFlag(f)) не будет он отличаться и технически. А уже семантику операции должно выражать ее название Get/Set - сам синтаксис языка тут не причем.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 04 Май, 2006 10:49 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 18:55
Сообщения: 2272
Откуда: Россия, Нижний Новгород
Вобщем, Vlad дело в следующем. Всё началось с того, что Вы заинтересовались почему в оберонах компилятором не контролируется обязательная инициализация переменных перед их использованием и сослались на языки Java/C#, в которых это делается. Я Вам показал какой ценой (в потере производительности) там (в C#) это достигается. Цена эта очень высокая. Да, конечно, контролировать обязательную инициализацию хорошо, но не любой же ценой! Уверен, что если когда-нибудь изобретут более приемлемый способ контроля, то он будет использован и в оберонах.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 04 Май, 2006 10:52 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Цитата:
Так вот, такие "гарантии" не стоят менее удобной записи и неинициализировнных переменных. Я бы даже сказал, что это вообще несравнимые вещи.

Насчет записи - для меня Обероновская кажется гораздо удобней. Единый стиль - все выходные данные, сколько бы их ни было, через OUT-параметры. Возвращаемые значения - либо указатели, либо некие числовые данные. Все по полочкам...
Неинициализированных переменных такие гарантии не стоят. Но они с ними никак и не связаны - я про то вообще и не говорил. Отсутствие защиты от неиниц. п. - действительно недочет. Возможно, если Ominc уже взялись расширять Оберон, то надо было в КП позволить в VAR-объявлениях указывать значения инициализации для полей, а явно не инициализированные забивать нулями. Или ввести до BEGIN секцию INIT, где всем необходимым полям/переменным можно присвоить результат каких-либо выражений, а остальные компилятор забьет нулями... На Ada можно посмотреть, опять же, в качестве примера.
Хотя лично я не разу не напарывался на ошибку неинициализированной переменной. Просто сам стиль мышления, какой пропагандируется в Оберонах - прежде чем написать строку кода, обеспечь все предусловия.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 04 Май, 2006 11:15 

Зарегистрирован: Вторник, 25 Апрель, 2006 16:21
Сообщения: 2180
Откуда: Нижний Новгород
Илья Ермаков писал(а):
Да, согласен, в С++ это не красиво. Как в Обероне? В Обероне и в том, и в другом случае принято передавать структуру по ссылке, только "ссылки" бывают разные: VAR, IN, OUT,
.

Если не ошибаюсь, собственно в Обероне и Обероне-2 нет IN и OUT. Они появились только в КП.

Илья Ермаков писал(а):
что позволяет явно указать, для чего передается ссылка на данные - для их изменения, только для чтения (тогда изменение внутри процедуры будет запрещено) или подчеркнуть то, что на входе данные могут быть неопределенными (но чтение все равно не запрещается).

А зря. Логичней было бы IN - только чтение. OUT - ТОЛЬКО запись. VAR - и то и другое.

Илья Ермаков писал(а):
PROCEDURE GetFlag(OUT f: MyFlag);
PROCEDURE SetFlag(IN f: MyFlag);
Таким образом, вызов двух таких процедур тоже "синтаксически никак не будет отличаться" (GetFlag(f), SetFlag(f)) не будет он отличаться и технически. А уже семантику операции должно выражать ее название Get/Set - сам синтаксис языка тут не причем.

Хех... Эдак оправдать можно и синтаксис вроде: ++a-=b+++++c;
Сказать, что мол названия переменных должны отражать сущность производимых операций... Ну в крайнем случае добавить коментарий.

На самом же деле НАМНОГО удобней (по крайней мере с т.з. чтения исходников. Чужих исходников.) Был бы синтаксис требующий при передаче параметров явно указывать для чего они передаются. Т.е.:
GetFlag(OUT: f) (* OUT - будет произведена запись в f *)
SetFlag(IN: f) (* IN - f будет прочитана, но точно не будет изменена *)

Причем возможно стоило бы сделать блоки ввода и вывода. Вроде:
MyProc(IN: a,b,c OUT: d,e,f)
Чтобы сразу при вызове функции(процедуры) было ясен набор входных параметров и набор того что она выдаст.

Сейчас же приходится скакать в место объявления процедуры чтобы узнать что она делает с параметрами и что она ожидает от них.

Фактически сейчас КП мало в этом плане отличается от С++, где тоже можно передавать нечто только для чтения:
void SetFlag (const &Flag f);

Из за неоднозначности синтаксиса вызова функции с параметром-ссылкой, в С++ рекомендуется этимне пользоваться, а пользоваться указателем т.к. фактически механизм тот же, но синтаксис более ясен.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 04 Май, 2006 11:51 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 18:55
Сообщения: 2272
Откуда: Россия, Нижний Новгород
Alexey Veselovsky писал(а):
OUT - ТОЛЬКО запись

Кстати, в языке C# ссылка out дополнительно означает, что запись в этот параметр нужно сделать обязательно. Хочешь - не хочешь, а в out параметр чего-то записать ты всё-равно обязан (хоть нули забить), иначе не скомпилируется. Вы к этому как относитесь? По моему это слишком сурово, лучше бы так: хочешь - записывай что-то в OUT переменную, а не хочешь - не записывай.

Alexey Veselovsky писал(а):
MyProc(IN: a,b,c OUT: d,e,f)

Правда, инкремент и декремент уж больно забавно будет выглядеть: INC(VAR: i, 10); DEC(VAR: j, 5); :)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 04 Май, 2006 11:51 

Зарегистрирован: Вторник, 25 Апрель, 2006 16:21
Сообщения: 2180
Откуда: Нижний Новгород
Илья Ермаков писал(а):
ними никак и не связаны - я про то вообще и не говорил. Отсутствие защиты от неиниц. п. - действительно недочет. Возможно, если Ominc уже взялись расширять Оберон, то надо было в КП позволить в VAR-объявлениях указывать значения инициализации для полей, а явно не инициализированные забивать нулями. Или ввести до BEGIN секцию INIT, где всем необходимым полям/переменным можно присвоить результат каких-либо выражений, а остальные компилятор забьет нулями... На Ada можно посмотреть, опять же, в качестве примера.


Я мало что смыслю в том как устроены компиляторы, как их создают и как они работают, но логично было бы чтобы любая вновь созданая переменная изначально была в режиме "только запись" до тех пор, пока в нее что-нибудь не запишут. Как в переменную что-то записали (проинициировали), так она становится открытой и для чтения и для записи.

Если же из нее пытаются что-то прочитать до момента первой записи (инициализации), то должна выскакивать ошибка.

Только боюсь, что тут нужна будет какая-то рантайм поддержка. Какой-то аналог сборщика мусора (нечто что будет отслеживать таковые переменные), хотя может и ошибаюсь.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Четверг, 04 Май, 2006 12:05 

Зарегистрирован: Вторник, 25 Апрель, 2006 16:21
Сообщения: 2180
Откуда: Нижний Новгород
Сергей Губанов писал(а):
Alexey Veselovsky писал(а):
OUT - ТОЛЬКО запись

Кстати, в языке C# ссылка out дополнительно означает, что запись в этот параметр нужно сделать обязательно. Хочешь - не хочешь, а в out параметр чего-то записать ты всё-равно обязан (хоть нули забить), иначе не скомпилируется. Вы к этому как относитесь? По моему это слишком сурово, лучше бы так: хочешь - записывай что-то в OUT переменную, а не хочешь - не записывай.

Могут быть ситуации, когда OUT-значение не должно быть изменено(грубо говоря, торчит какой-то внутри процедуры IF с параметрами в виде лог. выражения из входных параметров, и если оно истина, то выходное значение изменяется, если ложь, то нет), в этом случае запись в OUT - лишняя, бессмысленная работа. Причем в случае если OUT означает что из переменной читать нельзя, то мы ничего осмысленного туда записать не сможем. Т.к. чтобы не изменить OUT-параметр, мы должны были бы его вначале прочесть, а зетем записать в него тоже значение что и прочли.

Т.е. обязательность записи в OUT, если OUT у нас только на запись, не нужна. Более того - вредна.

Сергей Губанов писал(а):
Правда, инкремент и декремент уж больно забавно будет выглядеть: INC(VAR: i, 10); DEC(VAR: j, 5); :)

VAR можно опустить.
Т.е. INC(i, IN: 10)
Либо INC(i,10) (* я не знаю как объявленя INC, если второй параметр тоже как VAR, то так пойдет, иначе же - нет *)

Т.е. по умолчанию подразумевается VAR.
Если типы доступа в объявлении процедуры и в её использовании не совпадают, то ошибка.

Можно конечно еще упростить (сократить) запись, введя правило что передача константы (10) автоматически (по умолчанию) приравнивается к входному параметру (IN). Но стоит ли плодить исключения? Не знаю...


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 70 ]  На страницу Пред.  1, 2, 3, 4  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 13


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2024, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB