ФлеймФорумПрограммирование

Взялся за голову - начал изучать С++ (14 стр)

Страницы: 19 10 11 12 13 14
#195
15:23, 17 янв 2010

crsib
> Ты определись, компилятор или рантайм? Компилятор не может следить за ошибками времени исполнения. У std::vector тоже есть at(), который не позволит тебе выйти за границы массива. И с точки зрения конечного программиста, он (программист) не проверяет на выход за границы массива.

Наверное, я плохо объяснил. В ATS ничто не делается автоматически (там даже GC можно не использовать). Просто компилятор (а более точно -- проверка типов) следит за тем, чтобы программист, выделивший память, не забыл ее где-нибудь освободить (естественно, после того, как кусок памяти освободили, его уже нельзя будет использовать -- за этим тоже следит компилятор).

Это не то же самое, что RAII, хотя используется для (примерно) тех же целей.

> Эээ, автоматически закрывать открытые файлы? Автоматичски удалять хиповую память? А в чем проблема? При условии, что известен lifetime объекта. Для памяти вообще есть куча готовых решение, позволяющих тонко и точно контроллировать lifetime и отсутствие утечек.

Нет, не автоматически. :)

> Этим еще пользуются O_O? Один фиг, в приведенном тобой примере glEnd вызывается явно.

В приведенном мной примере glBegin()/glEnd() неважны. Важно то, что компилятор разрешает только "правильное" использование этих двух функций, на основе их типов.

> А они typesafe?

Еще как. :)

#196
15:27, 17 янв 2010

chiaroscuro

> Наверное, я плохо объяснил. В ATS ничто не делается автоматически (там даже GC можно не использовать). Просто компилятор (а более точно -- проверка типов) следит за тем, чтобы программист, выделивший память, не забыл ее где-нибудь освободить (естественно, после того, как кусок памяти освободили, его уже нельзя будет использовать -- за этим тоже следит компилятор).

Ты говорил о нем в контексте встроенного ПО. Я правильно понимаю, что если у меня ресурс выделяется в прерывании, а освобождается в потоке, которому передается через примитив ОС, то этому ATS придется объяснить, как работает железо и ОС?

PS
У меня еще есть вариант, когда мутекс лочится в потоке, а разлочивается в прерывании.

#197
15:55, 17 янв 2010

du_hast
> Ты говорил о нем в контексте встроенного ПО. Я правильно понимаю, что если у
> меня ресурс выделяется в прерывании, а освобождается в потоке, которому
> передается через примитив ОС, то этому ATS придется объяснить, как работает
> железо и ОС?
>
> PS
> У меня еще есть вариант, когда мутекс лочится в потоке, а разлочивается в
> прерывании.

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

Во-вторых, таки нет. :)

#198
16:45, 17 янв 2010

chiaroscuro

> таки нет. :)

Как ATS тогда поймет, что все в порядке? Что мутекс, который залочил поток в этом же потоке разлочивать не нужно, а он разлочится в прерывании, когда отработает железо. Железо, кстати, может не "отработать" если неправильно настроено или таки в нем косяк.

#199
17:09, 17 янв 2010

du_hast
> Как ATS тогда поймет, что все в порядке? Что мутекс, который залочил поток в
> этом же потоке разлочивать не нужно, а он разлочится в прерывании, когда
> отработает железо. Железо, кстати, может не "отработать" если неправильно
> настроено или таки в нем косяк.

По многопоточности в ATS я не читал и не делал (хотя примеры есть), поэтому не знаю. Вместо этого покажу пример на файловом IO (все равно паттерн со всеми ресурсами одинаковый: создание/выделение, потом использование, потом освобождение/удаление). Магии тут никакой.

(* функция actions принимает на вход path и ничего не возвращает *)
fun actions (path: string): void = let
  (* пробуем открыть файл по указанному пути на чтение, fp будет указателем FILE, а pfopt -- что-то типа переменной
   * если удалось, то fp будет ненулевым, а pfopt будет "ресурсом"
   *)
  prval (pfopt | fp) = fopen_err (path, file_mode_r)
in
  (* проверяем по указателю *)
  if fp <> null then let
    (* все ништяк, pf содержит доказательство того,
     * что по указателю fp лежит хэндл на открытый на чтение файл по пути path;
     * pf нам пригодится при работе с файлом, потому что каждой такой функции надо "предъявлять" его
     * (поэтому, если бы pf не было, то и работать дальше мы бы не смогли)
     *)
    prval Some_v (pf) = pfopt
  in
    (* тут должны быть какие-то дополнительные действия, но мы их опускаем.
     * закрывая файл, мы больше не можем использовать pf (ресурс "освобождается"), и следовательно, fp тоже *)
    fclose_exn (pf | fp)
    (* если fclose_exn пропустить, то компилятор скажет, что pf "выделен, но не освобожден" *)
  end else let
    (* никакого "токена" не получили *)
    prval None_v () = pfopt
  in
    (* выдаем ошибку в stderr *)
    prerrf ("actions(\"%s\"): failed to open\n", @(path))
  end
end

let ... in ... end -- это примерно то же самое, что в Си, когда в начале блока определяются все переменные.

Надо заметить, что никаких pfopt и pf во время работы программы не будет: они существуют только во время проверки типов.

правка: синтаксис

Страницы: 19 10 11 12 13 14
ФлеймФорумПрограммирование

Тема в архиве.