Автор Тема: А нужен ли в принципе контроль переполнения int типов  (Прочитано 12597 раз)

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Сабж применительно к современному универсальному ЯП (и оберону в частности)? Потому как мороки с обходом такого контроля (см. параллельную ветку) может быть больше, чем пользы (поймать ошибку в арифметических вычислениях). Особенно если речь идет о чем-то довольно низкоуровневом типа О-7. Ну и сделать такие проверки эффективными довольно сложно (без наворачивания оптимизатора).

akron1

  • Jr. Member
  • **
  • Сообщений: 76
    • Просмотр профиля
Если как в C# (checked/unchecked), то вполне может быть.

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Сабж применительно к современному универсальному ЯП (и оберону в частности)? Потому как мороки с обходом такого контроля (см. параллельную ветку) может быть больше, чем пользы (поймать ошибку в арифметических вычислениях). Особенно если речь идет о чем-то довольно низкоуровневом типа О-7. Ну и сделать такие проверки эффективными довольно сложно (без наворачивания оптимизатора).
Я в x86 не разбираюсь, ибо быдла ниграмытныя, но вот в msp430, если мне склероз не изменяет, после арифметических операций можно смотреть статусные битики в R2, где как раз в том числе будет обозначено и переполнение.

Вопрос в том, что при этом самом переполнении делать. Мое IMHO - игнорировать по умолчанию, НО иметь в языке возможность явным образом воткнуть эту самую проверку. типа CHECK(a+b) для любых типов и по умолчанию проверять для всех операндов если их тип checked.
Y = λf.(λx.f (x x)) (λx.f (x x))

Valery Solovey

  • Hero Member
  • *****
  • Сообщений: 509
    • Просмотр профиля
в x86 такой флажок тоже есть

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Думаю, что проверка нужна только на этапе разработки/тестирования.
В релизе слишком накладно тупо каждое присваивание контролить.

ps Хотя зависит от задачи.

Berserker

  • Sr. Member
  • ****
  • Сообщений: 254
    • Просмотр профиля
По умолчанию проверять, непроверяемые переменные помечать. С другой стороны, при переполнении в играх падать неприятно, что уж тут говорить. В таком случае можно в компиляторе предусмотреть вызов пользовательской процедуры, которая будет журналировать переполнение и только.

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
в x86 такой флажок тоже есть

Флажок проверять надо, а это медленно. Если б сразу исключение...

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
По умолчанию проверять, непроверяемые переменные помечать.

Я, наверное, соглашусь. По умолчанию таки проверять. Хотя, конечно, несколько коробит, что банальный ++i будет оттранслирован в что-то более громоздкое, чем ассемблерный inc.

trurl

  • Full Member
  • ***
  • Сообщений: 133
    • Просмотр профиля
В x86 есть INTO - это должно быть не слишком накладно.
А в языке можно завести "модулярные" целые, которые проверять не надо.
var x: integer (mod 4294967296);

Kemet

  • Hero Member
  • *****
  • Сообщений: 587
    • Просмотр профиля
проще будет ввести модификатор блока, например
VAR i: LONGINT;
BEGIN[CHECHRANGE]
  i := MAX(LONGINT);
  INC(i);
END;

Berserker

  • Sr. Member
  • ****
  • Сообщений: 254
    • Просмотр профиля
Переполнение может быт в тысячах мест. В тех же играх это ресурсы, характеристики, опыт и т.д. Весь код заполнить такими блоками не представляется целесообразным.

Jordan

  • Sr. Member
  • ****
  • Сообщений: 282
    • Просмотр профиля
проще будет ввести модификатор блока, например
VAR i: LONGINT;
BEGIN[CHECHRANGE]
  i := MAX(LONGINT);
  INC(i);
END;

Примерно так.

VAR i: LONGINT;
BEGIN
[CHECHRANGE = ON]
  i := MAX(LONGINT);
  INC(i);
[CHECHRANGE = OFF]
END;

Цель, убрать проверку полностью в программе и добавлять проверку в конкретном месте? К примеру при релизе, отключать проверку и перекомпилировать.

Kemet

  • Hero Member
  • *****
  • Сообщений: 587
    • Просмотр профиля
вообще такие проверки малореальны - машинный код превратится в нечто невразумительное с кучей проверок и ветвлений, на суперскалярах, скорее всего, производительность существенно просядет

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
В Аде (которую тут, походу, потихоньку изобретают) для этого есть специальные прагмы для компилятора:
http://en.wikibooks.org/wiki/Ada_Programming/Pragmas/Suppress
http://en.wikibooks.org/wiki/Ada_Programming/Pragmas/Unsuppress

procedure rangecheck_test is
   i: long_integer;
begin
   i := long_integer'Last;
   i := i + 1; -- тут предупреждения при компиляции
end rangecheck_test;
Builder results warning: value not in range of type "Standard.Long_Integer"
Builder results warning: "Constraint_Error" will be raised at run time

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

Вот наконец сделал нечто похожее:
with Text_IO, Ada.Integer_Text_IO; use Text_IO, Ada.Integer_Text_IO;

procedure rangecheck_test is
   procedure test (i: in out integer) is
   begin
      i := i + 1;
   end test;
   
   i: integer;
   
begin
   i := integer'Last;
   test(i);
   Put(i);
end rangecheck_test;
Здесь по умолчанию почему-то проверка переполнения отключается. Если включить прагмой
with Text_IO, Ada.Integer_Text_IO; use Text_IO, Ada.Integer_Text_IO;

procedure rangecheck_test is
   procedure test (i: in out integer) is
      pragma Unsuppress(Overflow_Check);
   begin
      i := i + 1;
   end test;
   
   i: integer;
   
begin
   i := integer'Last;
   test(i);
   Put(i);
end rangecheck_test;
то тогда при запуске сообщает об ошибке.

Ваще жесть эта Ада... о_О
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

trurl

  • Full Member
  • ***
  • Сообщений: 133
    • Просмотр профиля
В x86 есть INTO - это должно быть не слишком накладно.
Посмотрел спецификацию, INTO жрет 3 такта, зараза. Лучше было бы как с плавающей точкой: выставил флаг и пусть прерывается при переполнении.