OberonCore

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

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




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

Зарегистрирован: Вторник, 25 Апрель, 2006 16:21
Сообщения: 2180
Откуда: Нижний Новгород
Сергей Губанов писал(а):
Alexey Veselovsky писал(а):
MyProc(IN: a,b,c OUT: d,e,f)

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


INC(IN: i,10 OUT: i);

:-)

Но, кстати, сразу понятно что происходит. Более понятно чем INC(i,10); особенно если не знаешь что такое INC. :-)


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

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Сергей Губанов писал(а):
Я Вам показал какой ценой (в потере производительности) там (в C#) это достигается.


Ты ничего не показал. Повторяю еще раз: твой пример применительно к C# бессмысленен, потому что единственный осмысленный пример использования неинициализированной структуры (который я могу придумать) - это передача ее "куда-либо" для инициализации. Однако в C# это не нужно, потому что можно сразу получить структуру "откуда-либо" в готовом проиниченном виде. Другими словами: "на любом языке можно писать как на фортране", только не надо претензий к тому, что это неэффективно.

P.S. Слово "инвариант" тебе о чем-то говорит? Как в обероне обеспечить инвариант структуры?


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

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


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

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


Кстати, сама идея разнесения объявления и инициализации способствует появлению неинициализированных переменных.

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


В С++ все проще - объявляй переменную там, где она нужна :)


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

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Alexey Veselovsky писал(а):
в С++ рекомендуется этимне пользоваться, а пользоваться указателем т.к. фактически механизм тот же, но синтаксис более ясен.


На самом деле это на любителя. Указатели полностью не решают проблему и создают другие проблемы. Лично я на С++ предпочитаю возвращать все через возвращаемое значение, а не через параметры. Так нагляднее и проще выстраивать цепочки вызовов.


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

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


В VC8 такая поддержка есть.


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

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

Вы конечно правы, но на половину.

Рассмотрим пример.

Пусть есть следующая структура на языке C#:
Код:
public struct Data
{
  public double x, y, z;
}

Мы пишем свой инициализатор для этой структуры:
Код:
void MyInit (out Data a)
{
  a.x = 1; a.y = 2; a.z = 3;
}

Пытаемся его скомпилировать, но не можем :shock: :shock: :shock: Компилятор ругается:
Цитата:
The out parameter 'a' must be assigned to before control leaves the current method

Исправляем код:
Код:
void MyInit (out Data a)
{
  a = new Data();
  a.x = 1; a.y = 2; a.z = 3;
}

теперь всё компилируется. Но инициализация идёт два раза. В первый раз структура 'a' забивается нулями в "new Data()", и только потом она инициализируется числами 1, 2 и 3.

Хорошо, думаем мы, пусть это всё злой-плохой out-параметр. Напишем без него, вот так:
Код:
Data NewData ()
{
  Data a;
  a.x = 1; a.y = 2; a.z = 3;
  return a;
}

Пробуем скомпилировать, и опять, ёксель-моксель, не получается :shock: :shock: :shock: Компилятор ругается:
Цитата:
Use of unassigned local variable 'a'

Исправляем код:
Код:
Data NewData ()
{
  Data a = new Data();
  a.x = 1; a.y = 2; a.z = 3;
  return a;
}

Теперь компилируется, но эта процедура-функция получилась ещё тормознее первой. В самом деле, сначала структура 'a' инициализируется нулями, затем значениями 1, 2, 3; а потом, она ещё копируется инструкцией return туда куда надо. Аплодисменты. Занавес.


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

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Сергей Губанов писал(а):
Код:
Data NewData ()
{
  Data a = new Data();
  a.x = 1; a.y = 2; a.z = 3;
  return a;
}

Теперь компилируется, но эта процедура-функция получилась ещё тормознее первой.


Да, так уже лучше. А конструкторов (или списка инициализации) у структур в C# разве нет?

Сергей Губанов писал(а):
В самом деле, сначала структура 'a' инициализируется нулями, затем значениями 1, 2, 3; а потом, она ещё копируется инструкцией return туда куда надо. Аплодисменты. Занавес.


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


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

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

Циферки в комментариях:
Код:
namespace ValueTypePenalty
{
  public struct Data
  {
    public double x, y, z;
  }

  class Program
  {
    static Data NewData ()
    {
      Data a = new Data();
      a.x = 1; a.y = 2; a.z = 3;
      return a;
    }

    static Data g = new Data();
    static int count = 0;

    static void Do (int level)
    {
      if (level > 0)
      {
        // без инициализации структуры g, t = 3.475 секунд

        //g = new Data(); // t = 9.103 секунд

        g = NewData(); // t = 21.411 секунд

        count++;
        Do(level-1);
        Do(level-1);
      }
    }

    static void Main (string[] args)
    {
      int t = System.Environment.TickCount;
      Do(28);
      t = System.Environment.TickCount - t;
      System.Console.WriteLine("t = " + t + ", count = " + count);
      System.Console.ReadLine();
    }
  }
}

Vlad писал(а):
А конструкторов (или списка инициализации) у структур в C# разве нет?

В самую точку :D ! Конструкторы, конечно, есть. В них-то вся загвоздка. Если написать конструктор:
Код:
public struct Data
{
  public double x, y, z;
  public Data (double x, double y, double z)
  {
    this.x = x; this.y = y; this.z = z;
  }
}

и инициализировать посредством него: g = new Data(1, 2, 3), то всё будет летать: t = 4.747 секунд, что быстрее чем с конструктором по умолчанию :?, объяснить почему g = new Data(1, 2, 3) работает быстрее чем g = new Data() - я не могу.

Вывод: для каждой структруры надо писать конструктор.


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

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


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


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

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Сергей Губанов писал(а):
объяснить почему g = new Data(1, 2, 3) работает быстрее чем g = new Data() - я не могу.


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


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

Зарегистрирован: Понедельник, 28 Ноябрь, 2005 10:28
Сообщения: 1429
Vlad писал(а):
Alexey Veselovsky писал(а):
Если же из нее пытаются что-то прочитать до момента первой записи (инициализации), то должна выскакивать ошибка.
Только боюсь, что тут нужна будет какая-то рантайм поддержка.


В VC8 такая поддержка есть.

И в чем она заключается?


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

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Trurl писал(а):
Vlad писал(а):
В VC8 такая поддержка есть.

И в чем она заключается?


Диагностируются попытки использования непроиниченных переменных. В рантайме.


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

Зарегистрирован: Понедельник, 28 Ноябрь, 2005 10:28
Сообщения: 1429
А примерчик можно?


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

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Trurl писал(а):
А примерчик можно?


Код:
int f(int a)
{
int i;
    if (a > 0)
        i = a;
    return i;
}


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

Зарегистрирован: Понедельник, 28 Ноябрь, 2005 10:28
Сообщения: 1429
/RTCu ? Но это довольно дорого. И работает только для локальных переменных. Или в 8-е что-то улучшили?


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

Зарегистрирован: Понедельник, 28 Ноябрь, 2005 10:28
Сообщения: 1429
Vlad писал(а):
Повторяю еще раз: твой пример применительно к C# бессмысленен, потому что единственный осмысленный пример использования неинициализированной структуры (который я могу придумать) - это передача ее "куда-либо" для инициализации. Однако в C# это не нужно, потому что можно сразу получить структуру "откуда-либо" в готовом проиниченном виде.

А если мы читаем данные или выполняем вычисления и заполняем поля структуры по ходу дела?


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

Зарегистрирован: Вторник, 25 Апрель, 2006 16:21
Сообщения: 2180
Откуда: Нижний Новгород
Vlad писал(а):
Alexey Veselovsky писал(а):
в С++ рекомендуется этимне пользоваться, а пользоваться указателем т.к. фактически механизм тот же, но синтаксис более ясен.


На самом деле это на любителя. Указатели полностью не решают проблему и создают другие проблемы. Лично я на С++ предпочитаю возвращать все через возвращаемое значение, а не через параметры. Так нагляднее и проще выстраивать цепочки вызовов.


Аналогично. Там где это под моим контролем, стараюсь придерживаться правила:

ВЫХОД MyFunc(ВХОД);

Но так получается не всегда. Иногда функция должна вернуть несколько значений, но это еще можно обойти (возвращать через общюю структуру, сделать эти значения видимыми, реструктурировать программу так, чтобы данная функция должна была возвращать ровно одно значение). Но основная проблема в том, что например Win32 API сплош и рядом использует возврат значения через параметры (используя указатель), а в STL тоже в общем то обычная практика изменять нечто переданое в качестве параметра. Причем переданное в виде не указателя а ссылки. Например list::splice(iterator _Where,list<Allocator>& _Right,iterator _First);

+ код писаный не мною, а кем-то еще. В результате имеем в одном проекте не хилый зоопарк решений и подходов. Всё в куче. Что несколько раздражает и отвлекает.

В Обероне с этим чуть лучше - тут всё (кроме базовых типов) возвращается через параметры по ссыле. С одной стороны это единообразие (почти единообразие - таки возврат базовых типов через значение присутствует, и ясно впринципе зачем - чтобы можно было написать c := sqrt(a*a+b*b)), но с другой - единообразие в виде одного из наиболее невнятных (в плане синтаксиса вызова) механизмов, это не есть гут.

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


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

Зарегистрирован: Вторник, 25 Апрель, 2006 16:21
Сообщения: 2180
Откуда: Нижний Новгород
Vlad писал(а):
Alexey Veselovsky писал(а):
Если же из нее пытаются что-то прочитать до момента первой записи (инициализации), то должна выскакивать ошибка.
Только боюсь, что тут нужна будет какая-то рантайм поддержка.


В VC8 такая поддержка есть.


Отлично. Значит реализуемо.

Вопрос - насколько дорога такая поддержка?


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

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


Я не вникал в подробности. Просто код из VC6 (сгенерированный визардом) перестал работать ;)


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

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


И что это меняет? rturn MyStruct(calc(), read());


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

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


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

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


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

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